开发者社区> hopegrace> 正文
阿里云
为了无法计算的价值
打开APP
阿里云APP内打开

17、C++ Primer 4th 笔记,构造函数

简介: 1、构造函数初始化式只在构造函数的定义中而不是声明中指定。 2、从概念上讲,可以认为构造函数分两个阶段执行:(1)初始化阶段;(2) 普通的计算阶段。计算阶段由构造函数函数体中的所有语句组成。不管成员是否在构造函数初始化列表中显式初始化,类类型的数据成员总是在初始化阶段初始化。
+关注继续查看

1、构造函数初始化式只在构造函数的定义中而不是声明中指定。

2从概念上讲,可以认为构造函数分两个阶段执行:(1)初始化阶段;(2

普通的计算阶段。计算阶段由构造函数函数体中的所有语句组成。不管成员是否在构造函数初始化列表中显式初始化,类类型的数据成员总是在初始化阶段初始化。初始化发生在计算阶段开始之前。

3、使用构造函数初始化列表的版本初始化数据成员,没有定义初始化列表的构造函数版本在构造函数函数体中对数据成员赋值。

4、没有默认构造函数的类类型的成员,以及 const 或引用类型的成员,不管是哪种类型,都必须在构造函数初始化列表中进行初始化。

5、内置类型的成员不进行隐式初始化,对非类类型的数据成员进行赋值或使用初始化式在结果和性能上都是等价的。

6、成员被初始化的次序就是定义成员的次序。

7、按照与成员声明一致的次序编写构造函数初始化列表是个好主意。此外,尽可能避免使用成员来初始化其他成员。

8、初始化式可以是任意表达式。

9、我们更喜欢使用默认实参,因为它减少代码重复。

示例

#include "iostream"

using namespace std;

class Sales_item {
public:
	//default argument for book is the empty string
	Sales_item(const std::string &book = ""):
	  isbn(book), units_sold(0), revenue(0.0) { }
    Sales_item(std::istream &is);
	  // as before
private:
	string isbn;
	int units_sold;
	int revenue;
};

int main()
{
	Sales_item empty;
	Sales_item Primer_3rd_Ed("0-201-82470-1");
	return 1;
}

10、只有当一个类没有定义构造函数时,编译器才会自动生成一个默认构造函数。通常,在默认构造函数中给成员提供的初始值应该指出该对象是“空”的。

11、如何使用默认构造函数?

示例

Sales_item myobj();// oops! declares a function, not an object
//the following are right.
Sales_item myobj; //defines a class object ...
Sales_item myobj = Sales_item() //ok,create an unnamed, empty Sales_itemand use to initialize myobj

12、隐式类型转换

示例

class Salse_item
{
publi:
	Salse_item(const std::string &book = ""):isbn(book)...{}
	Salse_item(std::iostream &is);
	//explicit Salse_item(std::iostream &is);

	...
	bool same_isbn(Salse_item &si)
	{
	...
	}
};

int main()
{
	Salse_item item;
	string null_book = "12345";
	item.same_isbn(null_book); //会发生自动转换,把string类型转换成Salse_item型。
	item.same_isbn(cin);  ////会发生自动转换,把cin流类型转换成Salse_item型。
	//item.same_isbn(Salse_item(null_book)); //显式的进行转换
}

如上例中所示,我们构造了一个测试完成后被丢弃的对象,这个行为几乎是一个错误。

1)抑制由转换构造函数定义的隐式转换

声明为explicit,来停止隐式转换的上下文中使用构造函数。

2)如果真的需要转换,则显式的进行。

    通常,除非有明显的理由想要定义隐式转换,否则,单形参构造函数应该为 explicit

参考

[1] http://blog.163.com/zhoumhan_0351/blog/static/3995422720100250413207/

[2] http://blog.163.com/zhoumhan_0351/blog/static/39954227201032845132592/

[3] http://blog.163.com/zhoumhan_0351/blog/static/399542272010318112048522/

[4] http://blog.163.com/zhoumhan_0351/blog/static/39954227201032092854732/

[5] http://blog.163.com/zhoumhan_0351/blog/static/3995422720100284731826/

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
C++primer笔记之顺序容器
最近又重新拾起C++primer,发现每一次看都会有不同的体验,但每一次看后因为不常用,忘记得很快,所以记笔记是很关键的一环,咋一看是浪费时间,实际上是节省了很多时间。下面就把这一节的内容做一个简单的提炼和小节: 1、IO库类型不支持复制或赋值,因此,不能创建存放IO类型对象的容器。
787 0
38、C++ Primer 4th笔记,特殊工具与技术,嵌套类
1、在一个类内部再定义另外一个类,这样的类称为嵌套类(nested class),也称为嵌套类型(nested type)。嵌套类最常用于执行类。 嵌套类是独立的类,基本上与它们的外围类不相关,因此,外围类和嵌套类的对象是互相独立的。
688 0
32、C++ Primer 4th 笔记,多重继承与虚函数
1、只有在定义之后,类才可以用作多重继承的基类。按照基类构造函数在派生列表中的出现次序调用。 2、多重继承中,派生类的指针或引用可以转换为任意基类的指针或引用。 3、当一个类继承于多个基类的时候,那些基类之间没有隐含的关系,不允许使用一个基类的指针访问其它基类的成员。
742 0
20、C++ Primer 4th 笔记,重载运算符(1)
1、除了函数调用符之外,重载操作符的形参数目(包括成员函数的隐式this指针)与操作符的操作数目相同。函数调用操作符可以接受任意数目的操作数。 表1 可重载的操作符名 + - * / % ^ & | ...
852 0
22、C++ Primer 4th 笔记,到类类型与从类类型的转换
1、转换分为到类类型与从类类型的转换两种。到类类型的转换:通过转换构造函数;从类类型的转换:转换操作符。 2、常用16个操作符:5个算术操作符(+、-、*、/、%)及其对应的复合赋值操作符,4 个关系操作符(=),以及相等操作符(==、!=)。
737 0
9、C++ Primer 4th 笔记,string类型
1、string操作 string s; 定义一个新的空 string 对象,命名为 s string s(cp); 定义一个新的 string 对象,用 cp 所指向的(以空字符null 结束的)C 风格字符串(可以为字符串或字符数组,但是需以null结束)初始化该对象。
872 0
7、C++ Primer 4th 笔记,标准IO库(2)
1、文件的输入输出 由于历史原因,IO 标准库使用 C 风格字符串而不是 C++strings 类型的字符串作为文件名。 如果要把fstream对象与另一个不同的文件关联,则必须先关闭(close)现在的文件,然后打开(open)另一个文件。
953 0
6、C++ Primer 4th 笔记,标准IO库(1)
1、如果两种类型存在继承关系,则可以说一个类“继承”了其父类的行为-接口。IO 类型在三个独立的头文件中定义:iostream 定义读写控制窗口的类型, fstream 定义读写已命名文件的类型,而 sstream 所定义的类型则用于读写存 储在内存中的 string 对象。
876 0
+关注
698
文章
0
问答
文章排行榜
最热
最新
相关电子书
更多
低代码开发师(初级)实战教程
立即下载
阿里巴巴DevOps 最佳实践手册
立即下载
冬季实战营第三期:MySQL数据库进阶实战
立即下载