您的位置:首页 > 编程语言 > C语言/C++

C/C++中需要注意的一些问题

2015-03-06 16:52 295 查看

1. printf参数的压栈顺序

C中printf计算参数时是从右到左压栈的。考虑下面代码的输出结果:

[code]    int arr[] = { 0, 1, 2, 3 };
    int *p = arr;
    printf("%d, %d\n", *p, *(++p));


输出结果为“1, 1”。

2. 不允许复制构造函数传值参数

假如是传值参数,我们把形参复制到实参会调用复制构造函数。因此如果允许复制构造函数传值,就会在复制构造函数内调用复制构造函数,就会形成永无休止的递归调用从而导致栈溢出。

因此,C++标准不允许复制构造函数传值参数,在VS和GCC中都将编译出错。要解决这个问题,我们可以把构造函数的参数修改为const Type &t,也就是把传值参数改为常量引用。

3. 类成员变量的初始化顺序

类成员变量的初始化顺序只与它们在类中申明的顺序有关,而与在初始化列表中的顺序无关。

4. 派生类析构函数的执行顺序

派生类析构函数的执行顺序与构造函数正好相反:先执行派生类自己的析构函数,对派生类新增加的成员进行清理;然后调用子对象的析构函数,对子对象进行清理;最后调用基类的析构函数,对基类进行清理。

5. 虚析构函数

如果用new运算符建立了临时对象,若基类中有析构函数,并且定义了一个指向该基类的指针变量。在程序用带指针参数的delete运算符撤销对象时,会发生一个情况:系统只会执行基类的析构函数,而不执行派生类的析构函数。

如果将基类的析构函数申明为虚析构函数,那么将先执行派生类的析构函数,再执行基类的析构函数。

所以,建议是:最好把基类的析构函数申明为虚函数,这样所有的派生类的析构函数都自动成为虚函数了。

但是,构造函数不能申明为虚函数。这是因为在执行构造函数时类对象还未完成建立过程,当然谈不上函数与类对象的关联。

6. 纯虚函数

有时候在基类中将某一个成员函数申明为虚函数,并不是基类本身的需求,而是考虑到派生类的需要,在基类中预留了一个函数名,具体功能留给派生类根据需要去定义。这时可以将这个函数声明为一个纯虚函数。

纯虚函数是在声明虚函数时被“初始化”为0的函数。声明纯虚函数的一般形式是:

virtual 函数类型 函数名(参数列表) = 0;


如果在基类中没有保留函数名字,则无法实现多态性。如果在一个类中声明了虚函数,而在其派生类中没有对该函数定义,则该虚函数在派生类中仍然为纯虚函数。

7. 抽象类

不用类定义对象而只作为一种基本类型用作继承的类,称为抽象类。凡是包含纯虚函数的类都是抽象类。

因为纯虚函数是不能被调用的,包含纯虚函数的类是无法建立对象的。但是可以定义指向抽象类数据的指针变量,当派生类称为具体类之后,就可以用这种指针指向派生类对象,然后通过该指针调用虚函数,实现多态性的操作。

8. const iterator与const_iterator

[code]std::vector<int> vec;
// ...
const std::vector<int>::iterator iter = vec.begin(); // iter的作用就像一个T* const
*iter = 10; // 允许!改变iter所指向的对象
++iter; // 错误!iter是const

std::vector<int>::const_iterator cIter = vec.begin(); // cIter的作用就像一个const T *
*cIter = 10; // 错误!*cIter是const
++cIter; // 允许!


9. void指针的使用

参考:http://blog.csdn.net/yahohi/article/details/7551876
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: