关于C++的构造函数的几点注意
2011-08-18 14:42
295 查看
1. 构造函数初始化式于显示赋值的区别
与任何其他函数一样,构造函数具有名字、形参表和函数体。与其他函数不同的是,构造函数也可以包含一个构造函数初始化列表。a)Sales_item::Sales_item(const string &book): isbn(book), units_sold(0), revenue(0.0) { } b)Sales_item::Sales_item(const string &book) { isbn = book; units_sold = 0; revenue = 0.0; }合理的使用构造函数的初始化式是非常重要的,b)类 Sales_item 的成员赋值,但没有进行显式初始化。不管是否有显式的初始化式,在执行构造函数之前,要初始化isbn 成员。这个构造函数隐式使用默认的 string 构造函数来初始化 isbn。执行构造函数的函数体时,isbn 成员已经有值了。该值被构造函数函数体中的赋值所覆盖。
从概念上讲,可以认为构造函数分两个阶段执行:(1)初始化阶段;(2)普通的计算阶段。计算阶段由构造函数函数体中的所有语句组成。
不管成员是否在构造函数初始化列表中显式初始化,类类型的数据成员总是在初始化阶段初始化。初始化发生在计算阶段开始之前。两个版本具有同样的效果:无论是在构造函数初始化列表中初始化成员,还是在构造函数函数体中对它们赋值,最终结果是相同的。构造函数执行结束后,三个数据成员保存同样的值。不同之外在于,使用构造函数初始化列表的版本初始化数据成员,没有定义初始化列表的构造函数版本在构造函数函数体中对数据成员赋值。这个区别的重要性取决于数据成员的类型。
2.必须使用初始化列表的情况
有些成员必须在构造函数初始化列表中进行初始化。对于这样的成员,在构造函数函数体中对它们赋值不起作用。没有默认构造函数的类类型的成员,以及 const 或引用类型的成员,不管是哪种类型,都必须在构造函数初始化列表中进行初始化。因为内置类型的成员不进行隐式初始化,所以对这些成员是进行初始化还是赋值似乎都无关紧要。除了两个例外(const 和引用),对非类类型的数据成员进行赋值或使用初始化式在结果和性能上都是等价的。
例如,下面的构造函数是错误的:
class ConstRef { public: ConstRef(int ii); private: int i; const int ci; int &ri; }; // no explicit constructor initializer: error ri is uninitialized ConstRef::ConstRef(int ii) { // assignments: i = ii; // ok ci = ii; // error: cannot assign to a const ri = i; // assigns to ri which was not bound to an object } // ok: explicitly initialize reference and const members ConstRef::ConstRef(int ii): i(ii), ci(i), ri(ii) { }在许多类中,初始化和赋值严格来讲都是低效率的:数据成员可能已经被直接初始化了,还要对它进行初始化和赋值。比较率问题更重要的是,某些数据成员必须要初始化,这是一个事实。
相关文章推荐
- [c++ primer plus]c++ compiler缺省生成了哪些构造函数?关于构造函数的注意事项。
- 关于C++的类的几点注意点
- 关于C++语句的几点注意事项
- 关于喝牛奶的几点注意事项 - 生活至上,美容至尚!
- 关于使用SIO流的几点注意
- C++继承中关于子类构造函数的写法
- eclipse配置c++环境网上没有注意的几点
- 关于笔记本使用的几点注意事项
- 关于JAVA中的访问权限的几点注意
- 关于使用READ TABLE语句的几点注意事项
- 关于多线程的几点注意
- 做数据库繁体转简体项目后,关于对数据表操作时要注意几点
- [原创]关于C++的构造函数, 复制构造函数 和 operator =
- 关于C# 打包的几点注意事项
- C++初步~几点要注意的
- 构造函数的几点注意
- 关于前置声明与C++中头文件相互包含的几点问题
- 关于UrlReferrer传值的几点注意
- 一道关于C++ 的面试题目(继承、构造函数以及析构函数)
- 关于Linux文件系统的几点注意事项