当前位置:网站首页>3. Disabling copy construction
3. Disabling copy construction
2022-07-01 06:33:00 【HUSTER593】
List of articles
About C++ Copy constructor for , A lot of suggestions are to disable it directly . Why do you suggest that ? What are the limitations of not having a copy constructor ? How to disable copy construction ? This article makes a simple summary of these problems .
The problem discussed here takes the copy constructor as an example , But usually the assignment operator is implemented by copying the constructor Of ( copy-and-swap technology , See 《Exceptional C++》 A Book ), So the discussion here also applies to Fu Value operators , In general, when you disable the copy constructor, you also disable the assignment operator .
1 Why disable copy constructors
Why copy constructors are disabled , There are two main reasons I understand at present . The first is shallow copy , second The second is base class copy .
1.1 Shallow copy problem
The constructor generated by the compiler by default , yes memberwise Copy ( That is, copy the member variables one by one ), For the definition of the following class :
class Widget {
public:
Widget(const std::string &name) : name_(name), buf_(new char[10]) {
}
~Widget() {
delete buf_; }
private:
std::string name_;
char *buf_;
};
The default generated copy constructor , It will be copied directly buf_ Value , It leads to two problems Widget Object points to the same buffer , This can lead to the problem of deleting the same area twice during the deconstruction ( This problem is also called Double kill problem ).
There are many ways to solve this problem :
Write your own copy constructor , Then create a new... In the copy constructor
buf_, However, the copy constructor needs to consider the issue of exception security , So it's very difficult to write .Use
shared_ptrSuch a smart pointer , Let allWidgetObjects share a piece ofbuf_, and Give Wayshared_ptrThe reference counting mechanism helps you handle the deletion problem intelligently .Disable copy constructors and assignment operators . If you're not going to let
WidgetSupport copy , You can totally To disable both operations directly , thus , None of the problems mentioned above are problems .
1.2 Base class copy construction problem
If we don't write our own copy constructors , The compiler will automatically call the copy constructor of the base class to complete the copy of the base class :
class Base {
public:
Base() {
cout << "Base Default Constructor" << endl; }
Base(const Base &) {
cout << "Base Copy Constructor" << endl; }
};
class Drived : public Base {
public:
Drived() {
cout << "Drived Default Constructor" << endl; }
};
int main(void) {
Drived d1;
Drived d2(d1);
}
The output of the above code is as follows :
Base Default Constructor
Drived Default Constructor
Base Copy Constructor // Automatically called the copy constructor of the base class
But if we write for some reason , I wrote the copy constructor ( For example, because of the shallowness mentioned above Copy problem ), The compiler won't help us insert the copy constructor of the base class , It will only help us when necessary The default constructor of the base class :
class Base {
public:
Base() {
cout << "Base Default Constructor" << endl; }
Base(const Base &) {
cout << "Base Copy Constructor" << endl; }
};
class Drived : public Base {
public:
Drived() {
cout << "Drived Default Constructor" << endl; }
Drived(const Drived& d) {
cout << "Drived Copy Constructor" << endl;
}
};
int main(void) {
Drived d1;
Drived d2(d1);
}
The output of the above code is as follows :
Base Default Constructor
Drived Default Constructor
Base Default Constructor // Called the default constructor of the base class
Drived Copy Constructor
This is certainly not the result we want to see , In order to get the right results , We need to manually call the base class ourselves Copy the base class object .
Drived(const Drived& d) : Base(d) {
cout << "Drived Copy Constructor" << endl;
}
It wasn't a problem , It's just that some people forget that when they write copy constructors , Therefore, the sub objects of the base class are not copied normally , It's hard to detect BUG. So in order to solve these egg pain problems once and for all , Simply disable the copy construction and assignment operators .
2 There is no limit to copy construction
stay C++11 Before the object can be put into the container, it must have normal copy semantics , Objects with copy construction disabled cannot be placed directly into containers , Of course, you can use pointers to circumvent this , But you're in the dilemma of managing your own pointer ( Perhaps the use of smart pointers can alleviate this problem ).
C++11 There is mobile semantics in , You can put data in a container by moving it instead of copying it .
Another application of copy constructors is in design patterns Archetypal model , stay C++ There is no copy constructor in , this It may be difficult to implement these two patterns .
3 How to disable copy construction
If your compiler supports C++11, Use it directly
deleteOtherwise, you can declare the copy constructor and assignment operator as
privateNo implementation is provided at the same time .You can encapsulate the second step with a base class , Because the copy constructor generated by default will automatically call the copy of the base class Be , If the copy constructor of the base class is
private, So it can't access , It can't be normal Generate copy constructor .
class NonCopyable {
protected:
~NonCopyable() {
} // About why the statement became protected, Reference resources
// 《Exceptional C++ Style》
private:
NonCopyable(const NonCopyable&);
}
class Widget : private NonCopyable {
// On why to use private Inherit
// Reference resources 《Effective C++》 The third edition
}
Widget widget(Widget()); // error
It's not going to generate memberwise Copy constructor for , For details, please refer to 《 Depth exploration C++ The object model 》 One book .
4 summary
There are two main reasons for the ban :
- Shallow copy problem , That's the secondary decomposition mentioned above .
- Custom copy constructors for base and derived classes , But when a derived class object is copied , Called a copy of the derived class , Instead of calling the custom base class copy, call the default base class copy . This can cause insecurity , For example, in the case of secondary deconstruction , Because we won't call our custom base class deep copy , Or the default shallow copy .
5 appendix
Effective C++ Clause 6 Regulations , If you don't want to use functions generated automatically by the compiler , We should definitely refuse . There are three ways :
- C++11 Add... To the function declaration
deletekeyword :Base(const Base& obj) = delete;, There doesn't have to be a function body , When you call the copy construct again, you will report an error and try to refer to the deleted function . - The easiest way is to declare the copy constructor as
private - Clause 6 A better way to deal with it is given : Create a base class , Declare the copy constructor , But access rights are
private, All classes used inherit from this base class . The default copy constructor will automatically call the copy constructor of the base class , And the copy constructor of the base class isprivate, So it can't access , The copy constructor cannot be generated normally .
Qt That's what it does ,QObject There is a paragraph in the definition , All three are used :
The first method : The easiest way is to declare the copy constructor as private:
private:
Q_DISABLE_COPY(QMainWindow)
#define Q_DISABLE_COPY(Class) \ Class(const Class &) Q_DECL_EQ_DELETE;\ Class &operator=(const Class &) Q_DECL_EQ_DELETE;
The non - copyability of a class can be inherited , For example, those who inherit from QObject You can't use copy constructors or assignment operators on any of the classes .
The second method Inherit one uncopyable class
C++ Before the link , If we can solve this problem at compile time , It will save a lot of time , To solve the problem at compile time , You need to make some bug. We declare a base class that specifically blocks copying uncopyable.
class uncopyable{
protected:
uncopyable(){
}
~uncopyable(){
}
private:
uncopyable(const uncopyable&);
uncopyable& operator=(const uncopyable&);
}
Next , Our class just needs to inherit uncopyable, If a copy is going to happen , The compiler will try to call the copy constructor or assignment operator of the base class , But because the two are private , There will be compilation errors .
边栏推荐
- 绕圆旋转动画组件,拿过来直接用
- [ITSM] what is ITSM and why does it department need ITSM
- 基金定投是高风险产品吗?
- [unity shader ablation effect _ case sharing]
- 【#Unity Shader#自定义材质面板_第一篇】
- Although pycharm is marked with red in the run-time search path, it does not affect the execution of the program
- High order binary search tree
- 产品学习(三)——需求列表
- Mongodb: I. what is mongodb? Advantages and disadvantages of mongodb
- SQL学习笔记九种连接2
猜你喜欢

High order binary balanced tree
![[wechat applet] view container and basic content components](/img/25/181986ab4bf048854d1d1ca87de637.jpg)
[wechat applet] view container and basic content components

Free trial of self-developed software noisecreater1.1
![[unity shader amplify shader editor (ASE) Chapter 9]](/img/f5/f0f6786406e149187e71c8e12cde0d.png)
[unity shader amplify shader editor (ASE) Chapter 9]

C语言课设销售管理系统设计(大作业)

异常检测方法梳理,看这篇就够了!

概率论学习笔记

【Unity Shader 描边效果_案例分享第一篇】

Idea easy to use plug-in summary!!!

Promise
随机推荐
C语言课设职工信息管理系统(大作业)
【微信小程序低代码开发】二,在实操中化解小程序的代码组成
Although pycharm is marked with red in the run-time search path, it does not affect the execution of the program
Promise
HCM Beginner (III) - quickly enter pa70 and pa71 to browse employee information PA10
[unity shader amplify shader editor (ASE) Chapter 9]
考研目录链接
Restframework-simplejwt rewrite authentication mechanism
If I am in Guangzhou, where can I open an account? Is it safe to open an account online?
Teach you how to implement a deep learning framework
[summary of knowledge points] chi square distribution, t distribution, F distribution
Promise
Discrimination between left and right limits of derivatives and left and right derivatives
[automatic operation and maintenance] what is the use of the automatic operation and maintenance platform
Self confidence is indispensable for technology
[unity shader stroke effect _ case sharing first]
数据库产生死锁了请问一下有没有解决办法
@Transactional的传播属性REQUIRES_NEW深入理解
What is a port scanning tool? What is the use of port scanning tools
【#Unity Shader#自定义材质面板_第一篇】