Chinaunix首页 | 论坛 | 博客
  • 博客访问: 300231
  • 博文数量: 148
  • 博客积分: 4365
  • 博客等级: 上校
  • 技术积分: 1566
  • 用 户 组: 普通用户
  • 注册时间: 2008-07-05 21:38
文章分类
文章存档

2014年(2)

2013年(45)

2012年(18)

2011年(1)

2009年(54)

2008年(28)

我的朋友

分类: C/C++

2013-02-02 12:06:16

13章内容有点多,分开总结一下。

1. 前面提过,在声明构造函数或考构或某运算符后面加“=delete”,表示此函数不可用。

class base
{
public:
	base()= delete;
	base (const base&) = delete;

};
如果代码中有直接创建对象或使用拷贝构造函数的代码,编译会失败:

error: use of deleted function 'base::base()'

error: use of deleted function 'base::base(const base&)'

只要不想创建这个类的对象,语法上析构函数也可以声明为delete。


2. 如果是default关键字,则表示我们告诉编译器,直接使用你合成出来的就好。default可以在类外实现时加,但delete只能在类内声明时加。不过像下面这样把delete放在外面,4.6也编过了。但谁有心情把一delete函数搞在外面来写。

class Sales_data {
public:
    Sales_data() = default;

};
Sales_data& Sales_data::operator=(const Sales_data&) = default;
还有一点,default只能作用在编译器有能力合成的那些函数(con and copy control)和运算符上,delete无此限制。
class base
{
public:
	base()=default;
	void print()=delete;
	void print()=default;
};
首先default那行编译会失败:error: 'void base::print()' cannot be defaulted。

注释掉此行,编译OK。由base 对象调用print函数,又会失败:error: use of deleted function 'void base::print()'。

不想复制的类例如IO对象过去是把考构和赋值运算符声明为私有,新标准下,推荐使用delete形式。


3. copy control函数的合成规则

(1)类中某成员的析构函数是delete或私有,则该类的析构编译器会合成为delete;

(2)考构同上;

(3)赋值运算符同上,但多一条:如果类有const成员或者引用类型的成员,赋值运算符会合成为delete

class base
{
public:
	base():i3(3){}
	const int i3 ;
};
int main()
{
	base obj;
//	base obj2 = obj;

	base obj2;
	obj2 = obj;

	cout<<"end in main\n";
	return 0;
}
首先创建对象obj2时不要直接=obj,编译器会优化为使用考构貌似,验证本法则代码要先创建obj2,再赋值。编译器会有如下提示:

test.cpp:60:9: error: use of deleted function 'base& base::operator=(const base&)'
test.cpp:11:7: error: 'base& base::operator=(const base&)' is implicitly deleted because the default definition would be ill-formed:
test.cpp:11:7: error: non-static const member 'const int base::i3', can't use default assignment operator

换成引用也是如此,只不过提示换了,原因是可能改变原引用指向的对象?

non-static reference member 'int& base::i3', can't use default assignment operator

(4)最后看看默认的构造函数,规矩比较多:如果子成员的析构是deleter或私有,则构造为delete,变形金刚的一部分都搞不出来,整体也就没谱了;如果有引用成员,但没有使用类内初始化的形式,默认构造也会为delete,这个反正在4.6没试验出来,非静态成员不让用类内初始化,意思倒好理解,有个引用没初始化,默认构造无法创建;第三,有一个const成员其没有默认构造函数,或者没有对它进行类内初始化,则该类的默认构造也是delete。


总之:子成员无法创建或销毁,整个类就也不能进行。

阅读(4949) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~