C++易错知识点总结(一)...

来源:互联网 发布:unity3d ugui 动画 编辑:程序博客网 时间:2024/06/04 18:55

1. 在类内部定义的函数默认为inline类型的

 

2. 类的有些成员必须在构造函数初始化列表中进行初始化。对于这样的成员,在构造函数函数体中对他们赋值不起作用。这样类型的成员有:没有默认构造函数的类类型的成员,const或引用类型的成员(不管他们本身是什么类型的,int &a或是string &a),都必须在构造函数初始化列表中进行初始化。如下例:

 

3. 关于类成员被初始化的次序:

构造函数初始化列表仅用于初始化成员的值,并不指定这些初始化执行的次序。成员被初始化的次序就是定义成员的次序。如下例:

 

 

以上程序在初始化成员时,并不是按照初始化列表的次序先初始化m_i, 然后m_j, 而是按照这两个成员定义时的次序, 先初始化m_j, m_i, 于是出现了问题,在初始化列表中m_j(m_i), 也就是想用m_i去初始化m_j ,但这是m_i还没有被初始化, 所以会出现编译错误

 

C++ primer中推荐:最好按照与成员声明一致的次序编写初始化列表。而且,尽可能的避免使用类成员去初始化其他类成员。


 

4. 如果为类定义了其他的构造函数,则提供一个默认的构造函数( 无参)几乎总是对的。通常, 在默认构造函数中给成员提供的初始值应该指出该对象是的。

关于编译器提供的默认的构造函数对类成员初始化遵循以下规则,具有类类型的成员通过运行各自的默认构造函数进行初始化, 内置和复合类型的成员,如指针和数组, 只对定义在全局作用域中的对象才初始化, 当对象定义在局部作用域时,内置的或复合类型的成员不进行初始化。所以当类具有内置的或符合类型的成员是, 应该提供自定义的构造函数来初始化这些成员。

当一个类没有提供默认的构造函数时,它将失去以下功能:

(1)     不能用作动态分配数组的元素类型

(2)     静态定义的数组必须为每个元素提供一个显示的初始化式。

(3)     当将这个类型的对象放到诸如vector等的容器中时,不能只定义容器的大小而不提供元素的初始化式的构造函数。

 

 

5.关于构造函数定义的隐式转换

 如:

 

 

Testdisplay()函数需要一个Try类的对象,单是当我们传给他一个cin时, 编译也能够通过,这中间编译器给我们做了隐式的转换, 通过Try的构造函数Try(istream &is)进行了转换, 有时这种转换不是必须的,我们可以在声明构造函数时前面加上关键字explicit来切断这种隐式转换。

 

如:

 

 

这时在调用test.display()时必须显示的构造Try的对象了,test.display(Try(cin));

推荐:通常情况下, 要将单个形参的构造函数设置为explicit 防止发生隐式的转换, 造成不必要的错误.  Explicit关键字只能用于类内部定义的构造函数声明上,在类外部定义上不用。

 

6. 当我们将其他类的成员函数声明为友元函数时,必须使用该函数所属的类名字加以限定, 如:

 

 

7. 一些标记成员函数特殊类型的关键字:

Inline:可以放在声明处, 也可以放在定义处

Static:放在声明处, 无需放在定义处(在类内部定义除外,数据成员也是如此, 只需在声明处使用static定义处不能使用)

Explicit:放在声明处,不能放在定义处(在类内部定义的除外)

Const:声明处, 定义处都要有。

Friend: 放在声明处, 无需放在定义处(在类内部定义除外)

如:

 

 

8. const static数据成员在类的定义体中初始化时, 该数据成员仍需要在类的定义体外进行定义,如:

 

 

C++ primer上说const static类型的数据成员即使在类定义内部进行了初始化, 还是需要在类定义外部定义这个数据成员也就是上面的const int Try::MAX;句, 但是好像把这句去了编译也没问题

 

9.static类型成员不是类对象的组成部分, 所以static数据成员的类型可以是该成员所属的类类型, 而非static成员只能是改成员所属类类型的指针或引用. 如: