c++ primer 笔记第七章(二)

7.4 类的作用域

在类的作用域之外,普通成员可以使用对象、引用或指针访问,类类型可以用作用域运算符访问。

在类的外部,成员名字被隐藏起来了。

函数定义时遇到类名之后,定义的剩余部分就在类的作用域之内。

函数的返回值类型一般在函数名之外,若使用类类型成员,则需要使用作用域运算符访问。

7.4.1 名字查找与类的作用域

普通名字查找:一、在当前块名字使用之前寻找名字声明。二、未找到查找外层。 三、仍未找到报错。

类分为两步:一、先编译成员的声明。 二、编译成员函数的函数体。

类内成员函数可以使用类内所有地方声明的名字。

但是类型名的声明在成员声明里,因此使用类型名之前必须定义。且不能在类内重新定义类型名。

一般类型名的定义出现在类的开始处。

一般不建议使用类的成员名作为成员函数的形参名。不过可以使用this指针或者作用域运算符避免混淆。

在类外部定义成员时,不仅要考虑定义类之前的全局声明,还要考虑定义成员之前的全局声明。

7.5 构造函数再探

7.5.1 构造函数初始值列表

不在构造函数初始值列表里的成员,将在构造函数体执行之前执行默认初始化。

在执行函数体之前默认初始化可能带来未知影响,依赖于数据成员类型。

当成员是const或者引用或者未提供默认函数的类类型时必须初始化,因此必须使用构造函数初始值列表。

成员初始化的顺序和成员在类中声明顺序一致,与在构造函数初始值列表中顺序无关。

一般避免使用某成员初始化另外的成员。

如果一个构造函数所有参数都有默认实参,那么它实际上也定义了默认构造函数。

7.5.2 委托构造函数

c++11可以定义委托构造函数。

委托构造函数也有一个成员初始值列表和函数体。区别在于成员初始值列表只有唯一一个入口就是类名本身。

委托构造函数先执行受委托的构造函数,之后交还控制权给委托者函数。

7.5.3 默认构造函数的作用

当对象被默认初始化或者值初始化时自动执行默认构造函数。

类必须包含一个默认构造函数以便使用。

如果类包含一个没有默认构造函数的类成员,则该类不能被合成默认构造函数。

正确地使用默认构造函数,Sales_data obj;

7.5.4 隐式的类类型转换

如果构造函数只接受一个实参,则实际上定义了转换为此类型的隐式转换机制。这种构造函数也叫转换构造函数。

编译器智慧自动执行一步类型转换。item.combine(null_book); ok,string到对象。   item.combine("dsjlfssd") 不对,需要两步。

使用explicit关键字阻止构造函数进行隐式转换。只对有一个参数的构造函数有效,在类内声明时使用,定义不用。

explicit构造函数只能用于直接初始化,即Sales_data item1(null_book);。

explicit构造函数也可以用于显示强制转换。

7.5.5 聚合类

聚合类所有成员public;没有定义构造函数;没有类内初始值;没有基类,virtual函数。

使用花括号成员初始值列表初始化,顺序和定义相同。

7.5.6 字面值常量类

不是聚合类且1.数据成员都是字面值类型。 2.类内至少含有一个constexpr构造函数。3.如果数据成员有类内初始值那么一定是常量表达式。如果成员属于类类型,则初始值必须用成员的constexpr构造函数。4.类必须使用默认定义的析构函数。

constexpr构造函数必须初始化所有成员,初始值是常量表达式或者constexpr构造函数。

7.6 类的静态成员

静态成员使用static声明,只在类内使用,可以是private或者public。

静态成员函数不能声明为const型,也不能使用this指针,也不能调用非静态成员函数。

使用对象、引用或者指针都可以访问静态成员,也可以使用作用于运算符。类内可以直接使用。

可以在类内或者类外定义静态成员函数,类外定义时不加static。

类的静态数据成员必须在类外定义和初始化。

如果使用constexpr static 数据成员在类内使用常量表达式初始化,那么外部需要不带初始值的定义,若使用场景可以直接替换那么也可以不在外部定义。

静态成员独立于任何对象。静态类型可以是不完全类型甚至其本身类型的对象。

静态数据成员可以作为默认实参。

猜你喜欢

转载自blog.csdn.net/qq_25037903/article/details/81564667