一、p257~268构造函数、委托构造函数、隐式类类型转换、explicit的使用、聚合类、字面值常量类(constexpr)
二、p269~272 类的静态成员
学习内容:
一、
1)关于委托构造函数、隐式类类型转换的研究(p261~p265)
涉及:内容变量的初始化(参考页数p40默认初始化、p184~185局部对象)
#includeusing namespace std; //这里是全局域内定义了一个未初始化变量,它会被赋值为默认值 相当于int num1=default; int num1; class constA { public: constA(); constA(int); const int& getNum() const; constA& combine(const constA&); private: //而这里num声明在类内 和函数内一样从栈内存里分配了空闲的内存空间,可能还残存着上一次使用的数据未清理,所以值是无法预测的,并且不会赋予默认初始值。 //所以应该写成 int num=0; int num; }; //类外定义 //委托构造 无参数构造委托int参数的构造函数 //貌似子类调用父类的构造函数也是以这种委托的形式 constA::constA():constA::constA(0){} constA::constA(int a) { num = a; } constA& constA::combine(const constA& b) { num += b.getNum(); return *this; } const int& constA::getNum() const { return num; } / int main() { constA b; //隐式类类型转换 //combine(2)虽然函数没有int类型的重载 但是int的构造函数 是constA的参数构造函数之一,所以这里2会隐式地转换为constA的类型。 cout << b.combine(2).getNum() << endl; system("pause"); return 0; }
值得注意的地方,使用隐式的类类型转换必须要有相应的构造函数,而且这个构造函数只接受一个构造参数。 (p263 7.5.4处有提及)
2)explict的使用explict能抑制构造函数定义的隐式转换,和刚才所说的一样只作用于接收一个构造参数的构造函数,而且只能在类内声明的构造函数中使用,无需在类外定义时重复。(p265 中间处)
如果修改上面代码,加上explicit。
explicit constA(int);
那么下面combine(2)编译器就会报错
cout << b.combine(2).getNum() << endl;
3)聚合类
略。(就是定义一个数据结构)
4)字面值常量类与constexpr(再提及)
第一次提及在p213与内联函数一起解释。constexpr是指能用于常量表达式的函数,函数的返回类型和所有形参类型都是字面值类型,而且只能有一个return,它会被隐式地指定为内联函数。
第二次提及在p267与现在讨论的字面值常量类一起解释。值得注意的地方有:p268页提到的constexpr构造函数就必须既符合构造函数要求(不能包含返回语句),又符合constexpr函数的要求(拥有唯一可执行语句就是返回语句),从而作者给出结论就是一般函数体为空。(意思是函数结束的返回也算是返回语句吗?这句话理解得不是太好)
二、类的静态成员1)声明
使用static关键字进行声明。值得注意,类的静态成员存在于任何对象之外,意思是任何此类的对象都会公用同一份静态数据,它是存储在类对象的外部。(见p269)静态成员函数不能与const一起使用,以及不能使用this指针,因为它不属于任何具体对象。
2) 使用
在任何对象中都能用类对象、引用或者指针来访问静态成员。
3)定义
既可以在类外也可以在类内定义,但是在类外不要重复static关键字。(一般都是类外定义)
特殊情况下进行类内初始化,定义constexpr关键字,让static的成员变成常量,有点宏定义那味,但是作用在类内。
时间:7.12
暑期编程PK赛 得CSDN机械键盘等精美礼品!


