类基本概念3—默认构造函数
来源:互联网 发布:如何安装ubuntu系统 编辑:程序博客网 时间:2024/04/30 07:44
默认构造函数
只要定义一个对象时没有提供初始化式,就使用默认构造函数。为所有形参提供默认实参的构造函数也定义了默认构造函数。
1、合成的构造函数
一个类哪怕只是定义了一个构造函数,编译器也不会再生成默认构造函数。这条规则的根据是,如果一个类在某种情况下需要控制对象初始化,则该类很可能在所有情况下都需要控制。
只有当一个类没有定义构造函数时,编译器才会自动生成一个默认构造函数。
如果类包含内置或复合数据类型的成员,则该类不应该依赖于合成的默认构造函数。他应该定义自己的构造函数来初始化这些成员!
如果每个构造函数将每个成员设置为明确的已知状态,则成员函数可以区分空对象和具有实际值的对象。
2、类通常定义一个默认构造函数
假定有一个NoDefault类,它没有定义自己的默认构造函数,却有一个接受一个string实参的构造函数。因为该类定义了一个构造函数,因此编译器将不合成默认构造函数。NoDefault没有默认构造函数,意味着:
1)具有NoDefault成员的每个类的每个构造函数,必须通过传递一个初始的string值给NoDefault构造函数来显式地初始化NoDefault成员。
2)编译器将不会为具有NoDefault类型成员的类合成默认构造函数。如果这样的类希望提供默认构造函数,就必须显式地定义,并且默认构造函数必须显式地初始化其NoDefault成员。
3)NoDefault类型不能用作动态分配数组的元素类型。
4)NoDefault类型的静态分配数组必须为每个元素提供一个显式的初始化式。
5)如果有一个保存NoDefault对象的容器,例如vector,就不能使用接受容器大小而没有同时提供一个元素初始化式的构造函数。
实际上,如果定义了其他的构造函数,则提供一个默认构造函数几乎总是对的。通常,在默认构造函数中给成员提供的初始值指出该对象是空的!
总之:不管有没有重载构造函数,最好都给出一个默认构造函数
3、使用默认构造函数
使用默认构造函数定义一个对象的:
- Sales_item myObj;
或者是:
- Sales_item myObj = Sales_item();
编译器创建并初始化一个Sales_item对象,然后用它来按值初始化myObj。但是不能是下面这种形式:
- //myObj的定义被编译器解释为一个函数的声明!!!
- Sales_item myObj();
隐式类类型转换
- class Sales_item
- {
- public:
- Sales_item(const std::string &book):
- isbn(book),units_sold(0),revenue(0) {}
- Sales_item(istream &in);
- bool same_isbn(const Sales_item &item)
- {
- return isbn == item.isbn;
- }
- private:
- std::string isbn;
- unsigned units_sold;
- double revenue;
- };
在这儿其实每个构造函数都定义了一个隐式转换!!!因此,在期待Sales_item类型对象的地方,可以使用一个string或者istream:
- string null_book("9-999-99999-9");
- item.same_isbn(null_book); //<希望通过string构建临时的类对象,但是注意这个对象的作用域
- item.same_isbn(cin);
由于这个Sales_item对象是一个临时对象。一旦same_isbn结束,就不能再访问它。实际上,我们构造了一个在测试完成后被丢弃的对象。这个行为几乎肯定是一个错误。
1、抑制由构造函数定义的隐式转换
可以通过将构造函数声明为explicit,来防止在需要隐式转换的上下文中使用构造函数:
- explicit Sales_item(const std::string &book):
- isbn(book),units_sold(0),revenue(0) {}
- explicit Sales_item(istream &in);
- item.same_isbn(null_book); //Error
- item.same_isbn(cin); //Error
- //Error
- explicit Sales_item::Sales_item(istream &is) 说明:explicit只能用于类内部的构造函数的声明:
- {
- is >> *this;
- }
2、为转换而显式地使用构造函数
- item.same_isbn(Sales_item(null_book));
- item.same_isbn(Sales_item(cin));
显式使用构造函数只是终止了隐式地使用构造函数。任何构造函数都可以用来显式地创建临时对象!
【最佳实践】
通常,除非有明显的理由想要定义隐式转换,否则,单形参构造函数应该为explicit(通常因为只有一个形参的时候就会出现上面隐式转换的情况,但是这样经常会引入局部临时变量引起错误)。将构造函数设置为explicit可以避免错误,并且当转换有用时,用户可以显式地构造对象。
- 类基本概念3—默认构造函数
- 类的默认构造函数
- 类的默认构造函数
- C++基本概念——构造函数
- 派生类的构造函数--基本概念
- 第四周项目1—三角形类的构造函数(3)使用有默认参数的构造函数
- 三角形类——使用默认参数的构造函数
- 第五周—1.1三角形类(默认构造函数)
- 第四周项目一——三角形类的构造函数——默认构造函数
- 第3周-项目1-三角形类的构造函数-默认构造函数
- 第3周-项目1-三角形类的构造函数-有默认参数的构造函数
- 第四周项目一 三角形类构造函数(3) 带默认参数的构造函数
- 第四周项目1—三角形类的构造函数(2)设计默认构造函数
- 第四周 项目一 三角形类的构造函数—设计默认构造函数
- C++构造函数语义——默认构造函数
- C++构造函数语义——默认构造函数
- C++构造函数语义——默认构造函数
- C++构造函数语义——默认构造函数
- SHELL函数返回字符串的方法
- asp.net MVC + linq to Entity简单教程(五)linq to Entity中join的使用以及子查询
- 【深入】java 单例模式
- HDU 5024 - Wang Xifeng's Little Plot(暴力搜索)
- HDU 5024 Wang Xifeng's Little Plot(广州网络赛C题)
- 类基本概念3—默认构造函数
- 微信商城+电脑商城多用户源码+个人免签支付宝 +24套微信店铺模
- Boyer-Moore 字符串匹配算法
- Python中利用ConfigParser操作配置文件
- 2014华为机试——地铁换乘寻找最少车站数和排序算法
- atal error LNK1123 解决办法
- MongoDB权限
- 数据结构学习总结
- mysql错误提示Illegal mix of collations (gbk_chinese_ci,IMPLICIT) and (utf8_general_ci,COERCIBLE)