《C++ Primer》读书笔记第七章-3-构造函数再探 And 类的静态成员
2017-09-16 20:29
232 查看
笔记会持续更新,有错误的地方欢迎指正,谢谢!
总结:如果成员是const、引用或者属于某种未提供默认构造函数的类类型,我们必须通过构造函数初始值列表为这些成员提供初值。
另外,成员的初始化顺序与它们在类定义中的出现顺序一致,而与初始化列表无关,这句话经常考!
例子:
这样是错的。因为怎么能用未初始化的j去初始化i呢?
最好的方式是用构造函数传进来的参数去初始化成员,这样我们就不用考虑初始化顺序了:
默认实参和构造函数:
默认构造函数是没有参数的,但我们可以这么干:
这是这个类的默认构造函数,它用到了默认实参,这么写的好处是:
不传参数时,也能调用(就相当于默认构造函数,它就用空字符串s去初始化bookNo。)
传参数时,就按照传的来呗。一石二鸟呗,实用哈。
默认构造对象:使用默认构造函数定义对象的格式为类名+对象名,后面没有空括号,否则就变成了定义函数。
什么样的类是聚合类呢?满足下面四个条件:
1.所有成员都是public;
2.没有定义任何构造函数;
3.没有类内初始值;
4.没有基类,也没有virtual函数;
5.使用花括号初始化;
6.花括号内的初始值顺序与声明顺序一致。
举例:
不讲了。
例如:银行账户类和利率成员,我们希望利率成员与类直接关联,而不是和银行卡对象关联。也就是,一旦利率成员变化,我们希望所有的银行卡对象都能使用新值。
声明静态成员
使用类的静态成员
使用类作用域运算符::直接访问:
同样可用对象去访问静态成员
以上是在类外访问,如果在类内呢?直接访问呗。
定义静态成员
类的静态成员应该在类内声明,类外定义。类成员函数的声明只能放在类内,在类外部定义静态成员时,不能再用static关键字,该关键字只能出现在类内部的声明语句。
我们来定义一个在类内已经声明的static成员:
静态数据成员一旦被定义,就一直存在于程序的整个生命周期中。
静态成员的类内初始化
刚刚说过,类的静态成员应该在类外定义,于是C++又来破坏自己定的规矩了。什么狗屁东西,不学了!食之无味弃之可惜。
静态成员能用于某些场景,而普通成员不能
由于静态成员独立于任何对象,所以静态数据成员可以是不完全类型。
不完全类型的特殊情况:静态数据成员可以是它所属的类类型。
而非静态数据成员则受限制,只能声明成它所属类的指针或引用,才可如此用。如下方的
因为静态成员一般在外面定义初始化,所以,在类内可以是不完全类型,便可胡作非为。
总结:静态成员的优势:
类内可包含自身类型的静态数据成员,但普通成员只能是指针或引用;
静态成员可以作为默认实参,非静态数据成员的值属于对象的一部分,不能作为默认实参。因为静态成员与类绑定,是类的所有对象来共享的。所以类的对象不同时就用不了咯~(此优势未举例,自己领会哈~)
本章小结:
类允许我们为自己的应用特制类型
类有两项基本能力:
数据抽象,就是定义数据成员和函数成员
封装,保护类的成员不被随意访问(private,友元等)
构造函数可以控制初始化对象的方式
静态成员与类绑定,存在于对象之外,是所有对象来共享的。
构造函数再探
构造函数初始值列表
我们初始化 const数据 或 引用类型的数据 的唯一机会就是通过构造函数初始值,于是我们可以这么写:class ConstRef { public: ConstRef(int value) : i(value), ci(value), ri(i){} private: int i; const int ci; int &ri; };
总结:如果成员是const、引用或者属于某种未提供默认构造函数的类类型,我们必须通过构造函数初始值列表为这些成员提供初值。
另外,成员的初始化顺序与它们在类定义中的出现顺序一致,而与初始化列表无关,这句话经常考!
例子:
class X { int i; int j; public: X(int val) : j(val), i(j){}//i先被初始化。 };
这样是错的。因为怎么能用未初始化的j去初始化i呢?
最好的方式是用构造函数传进来的参数去初始化成员,这样我们就不用考虑初始化顺序了:
X(int val) : i(val), j(val){}
默认实参和构造函数:
默认构造函数是没有参数的,但我们可以这么干:
class Sales_data { public: Sales_data(string s = "") : bookNo(s){} }
这是这个类的默认构造函数,它用到了默认实参,这么写的好处是:
不传参数时,也能调用(就相当于默认构造函数,它就用空字符串s去初始化bookNo。)
传参数时,就按照传的来呗。一石二鸟呗,实用哈。
委托构造函数
就是调用 普通的构造函数 帮忙初始化。默认构造函数的作用
记住一条好习惯:如果定义了其他的构造函数,最好也提供一个默认构造函数,下面来看一个没有默认构造函数的经典错误:class NoDefault { public: NoDefault(const string &);//定义了构造函数,但没有定义默认构造函数。 }; struct B { B(){} NoDefault b; //b作为类类型成员,构造函数没有初始化它,于是它会调用默认构造函数初始化,结果该死的NoDefault没有默认构造函数。 };
默认构造对象:使用默认构造函数定义对象的格式为类名+对象名,后面没有空括号,否则就变成了定义函数。
聚合类
此类不常用~什么样的类是聚合类呢?满足下面四个条件:
1.所有成员都是public;
2.没有定义任何构造函数;
3.没有类内初始值;
4.没有基类,也没有virtual函数;
5.使用花括号初始化;
6.花括号内的初始值顺序与声明顺序一致。
举例:
struct Data { int val; string s; }; Data a = {0, "temp"}; //实例化,一定要按类内定义的顺序来初始化。
字面值常量类
此类不常用~不讲了。
类的静态成员
有时候,类需要它的一些成员与类本身直接相关。例如:银行账户类和利率成员,我们希望利率成员与类直接关联,而不是和银行卡对象关联。也就是,一旦利率成员变化,我们希望所有的银行卡对象都能使用新值。
声明静态成员
static double interestRate;
使用类的静态成员
使用类作用域运算符::直接访问:
double r; r = Account::rate();
同样可用对象去访问静态成员
Account c1; Account *ac2 = &ac1; r = ac1.rate(); r = ac2->rate();
以上是在类外访问,如果在类内呢?直接访问呗。
定义静态成员
类的静态成员应该在类内声明,类外定义。类成员函数的声明只能放在类内,在类外部定义静态成员时,不能再用static关键字,该关键字只能出现在类内部的声明语句。
我们来定义一个在类内已经声明的static成员:
double Account::interestRate = initRate();
静态数据成员一旦被定义,就一直存在于程序的整个生命周期中。
静态成员的类内初始化
刚刚说过,类的静态成员应该在类外定义,于是C++又来破坏自己定的规矩了。什么狗屁东西,不学了!食之无味弃之可惜。
静态成员能用于某些场景,而普通成员不能
由于静态成员独立于任何对象,所以静态数据成员可以是不完全类型。
不完全类型的特殊情况:静态数据成员可以是它所属的类类型。
而非静态数据成员则受限制,只能声明成它所属类的指针或引用,才可如此用。如下方的
Bar *m2;
class Bar { private: static Bar m1; //这个牛,因为m1是不完全类型的特殊情况。 Bar *m2;//这个也牛,所属类的非静态数据成员的指针 也是不完全类型。 static int &m2; //这个更牛,未初始化的引用。因为m2是不完全类型~ };
因为静态成员一般在外面定义初始化,所以,在类内可以是不完全类型,便可胡作非为。
总结:静态成员的优势:
类内可包含自身类型的静态数据成员,但普通成员只能是指针或引用;
静态成员可以作为默认实参,非静态数据成员的值属于对象的一部分,不能作为默认实参。因为静态成员与类绑定,是类的所有对象来共享的。所以类的对象不同时就用不了咯~(此优势未举例,自己领会哈~)
本章小结:
类允许我们为自己的应用特制类型
类有两项基本能力:
数据抽象,就是定义数据成员和函数成员
封装,保护类的成员不被随意访问(private,友元等)
构造函数可以控制初始化对象的方式
静态成员与类绑定,存在于对象之外,是所有对象来共享的。
相关文章推荐
- [转]《Java Generics and Collections》读书笔记四:构造函数,静态成员,嵌套类
- 《C++ Primer》读书笔记第七章-2-类的其他特性 And 类的作用域
- 《C++ Primer》读书笔记第七章-1-抽象数据类型 And 访问控制与封装
- C++语言特性:构造函数,析构函数,虚函数,内联函数,静态成员函数,重载,覆盖,隐藏
- 类和对象(字段=变量、方法=函数、方法重载、静态成员、属性、构造函数)
- C++ Primer 读书笔记 – 第七章
- 【转载】c++之类的基本操作(c++ primer 的读书笔记 ,类对象, 类用户, 类成员的含义)
- 《Effective C#》Item 13:使用静态构造函数初始化静态成员
- JS之稳妥构造函数模式and静态私有变量
- [C#]C#补习——静态构造函数、静态成员和常量相关
- C++ Primer 读书笔记 – 第七章
- Java中的初始化顺序(静态成员、静态初始化块,普通成员、普通初始化块、构造函数)
- C#箴言:用静态构造函数初始化静态成员
- virtual与构造/析构函数(内联函数,构造函数,静态成员函数不能为virtual函数)
- C++的构造函数属性初始化_静态成员_this指针
- c++笔记(6):类、对象、构造函数、析构函数、静态成员、友元、类包含
- C#学习之静态成员和非静态成员,构造函数,方法,方法参数,操作符重载,事件
- 13.用静态构造函数初始化类的静态成员
- 用静态构造函数初始化静态成员_