前言
在写代码的时候发现一个bug,编译器报错,报
/usr/include/c++/9/ext/new_allocator.h:145:20: error: use of deleted function
最后发现了原因,是因为我们隐式的调用了copy构造函数,但是,copy构造函数被我们显示的删除了(=delete ),由此我们探讨一下C++ 11的=delete 特性
代码
先看一个正常的copy构造函数
#include <iostream>
#include <list>
using namespace std;
class A{
public:
A(const A&){
cout << "copy construct" << "\n";
}
A( int id)
:class_id(id){
cout << "normal construct" << "\n";
}
private:
int class_id;
};
int main()
{
list<A> a;
a.push_front(A(1));
a.push_front(A(2));
return 0;
}
我们知道在一个list中push一个class会隐式的调用copy构造,或者移动构造,2者都存在先调用移动构造,具体看这里,因为项目的一些历史原因有的class的拷贝构造被赋予了=delete ,这说明编译器明令禁止调用对应函数,所以会导致报错,我们看一下
#include <iostream>
#include <list>
using namespace std;
class A{
public:
A(const A&) = delete;
A( int id)
:class_id(id){
cout << "normal construct" << "\n";
}
private:
int class_id;
};
int main()
{
list<A> a;
a.push_front(A(1));
a.push_front(A(2));
return 0;
}
再看输出
/usr/include/c++/9/ext/new_allocator.h:145:20: error: use of deleted function ‘A::A(const A&)’
上述代码禁止我们使用Class A的拷贝构造函数,所以在push的时候隐式的调用copy构造是非法的
考虑一个更深层次的问题,为什么我们需要禁用拷贝构造函数? 我们知道拷贝构造函数会将其内存中的对应值都拷贝进另一个对象中,假如这个值非常的大就比较悲催了,所以我们在某一些场合会禁用拷贝构造 还有一种情况,我们的class中有个成员是动态数组,我们用拷贝构造将这个数组传入到新的class中,会导致有2个指针变量指向一个地址的情况,因为默认构造函数会尝试copy全部的成员…如下代码所示
#include <iostream>
#include <list>
using namespace std;
class A{
public:
A( int id, int d)
:class_id(id),data(d){
cout << "normal construct" << "\n";
}
int getclassid(){ return class_id; }
int getdata(){ return data; }
private:
int class_id;
int data;
};
int main()
{
A a(1,2);
cout << "A's class id is " << a.getclassid() << " A's data is " << a.getdata()<<"\n" ;
A b = a;
cout << "B's class id is " << b.getclassid() << " B's data is " << b.getdata() << "\n";
return 0;
}
输出如下
normal construct
A's class id is 1 A's data is 2
B's class id is 1 B's data is 2
总结
我们在写cpp的时候业务工程比较复杂,class比较多,也许会出现一个class包含另一个class的情况,比如class A里面包含了另一个class B,此时我们又正好对class A做操作,这个操作又正好隐式的引发拷贝构造,又恰好class A没有定义拷贝构造,编译器给他搞了一个默认的拷贝构造函数,默认拷贝构造函数尝试拷贝class A的所有变量给其他的class,包括class A中的成员class B(拷贝过程中会隐式的引发class B的拷贝构造),又恰好class A中的成员class B禁止拷贝构造B(const B&)=delete; 此时就会报出如下的错误
/usr/include/c++/9/ext/new_allocator.h:145:20: error: use of deleted function ‘B::B(const B&)
|