为什么当我做复制和交换习语时不调用我的复制构造函数?
why isn't my copy constructor called when I do a copy and swap idiom?
在下面的代码中,当使用赋值运算符时,为什么没有调用复制构造函数或为什么没有与之对应的打印?
#include <iostream>
#include <cstring>
using std::cout;
using std::endl;
class Person {
private:
char* name;
int age;
public:
Person() {
name = nullptr;
age = 10;
}
Person(const char* p_name, int p_age) {
name = new char[strlen(p_name) + 1];
strcpy(name, p_name);
age = p_age;
}
Person(Person const& p) {
cout << "Person copy constructor with " << p.name << endl;
name = new char[strlen(p.name) + 1];
strcpy(name, p.name);
age = p.age;
}
/*self assignment
The first is the self-assignment test. This check serves two purposes: it's an easy way to prevent us from running needless code on self-assignment,
and it protects us from subtle bugs (such as deleting the array only to try and copy it).
But in all other cases it merely serves to slow the program down, and act as noise in the code; self-assignment rarely occurs, so most of the time
this check is a waste. It would be better if the operator could work properly without it.*/
/*
Person& operator=(Person const& p) {
cout << "Person copy assignment with " << p.name << endl;
if(this != &p){
delete[] name;
name = nullptr;
name = new char[strlen(p.name) + 1];
strcpy(name, p.name);
age = p.age;
}
return *this;
}
*/
/*exception safety
If in the previous approach the memory allocation fails and throws an exception then the data in name is gone*/
/*
Person& operator=(Person const& p) {
cout << "Person copy assignment with " << p.name << endl;
char* temp_name = new char[strlen(p.name) + 1];
strcpy(temp_name, p.name);
delete[] name;
name = temp_name;
age = p.age;
return *this;
}
*/
//copy and swap idiom
/*
. Not only that, but this choice is critical in C++11, which is discussed later.
(On a general note, a remarkably useful guideline is as follows: if you're going to make a copy of something in a function,
let the compiler do it in the parameter list.‡)
*/
Person& operator=(Person p) {
cout << "Person copy assignment with " << p.name << endl;
swap(*this, p);
return *this;
}
/*
A swap function is a non-throwing function that swaps two objects of a class, member for member. We might be tempted to
use std::swap instead of providing our own, but this would be impossible; std::swap uses the copy-constructor and
copy-assignment operator within its implementation, and we'd ultimately be trying to define the assignment operator in terms of itself!
*/
friend void swap(Person &a, Person &b) {
using std::swap;
swap(a.name, b.name);
swap(a.age, b.age);
}
Person(Person&& other) {
swap(*this, other);
}
~Person() {
if(name)
cout << "Person destructor called for " << name << endl;
delete[] name;
}
};
int main() {
Person p("Ryan", 28);
Person a(p);
a = p;
cout << "Hello World" << endl;
return 0;
}
上述代码的输出为:
Person copy constructor with Ryan
Person copy constructor with Ryan
Person copy assignment with Ryan
Person destructor called for Ryan
Hello World
Person destructor called for Ryan
Person destructor called for Ryan
为什么没有调用复制构造函数/没有与之对应的打印。
实际上,它被称为很好。您可以在自己的输出中看到:
Person copy constructor with Ryan
Person copy constructor with Ryan <--- This is it : )
Person copy assignment with Ryan
请参阅此处的呼叫站点:
a = p;
这是您的赋值运算符:
Person& operator=(Person p) {
cout << "Person copy assignment with " << p.name << endl;
swap(*this, p);
return *this;
}
所以复制构造函数在这里被调用给谁? 什么时候?在输入operator=
代码正文之前,p
调用此参数(使用调用站点=
的 RHS 作为其参数(。因此,在输出中,您将其视为与此相邻的行:
Person copy assignment with Ryan
相关文章:
- 当从函数参数中的临时值调用复制构造函数时
- 使用仅使用一次的变量调用的复制构造函数.这可能是通过调用move构造函数进行编译器优化的情况吗
- 为什么类中的ostringstream类型的成员会导致";调用隐含删除复制构造函数";错误
- 为什么默认复制函数在按值发送参数时不调用?
- 为什么调用复制构造函数而不是移动构造函数?
- C++ 基本 CTOR 说明 - 为什么不调用赋值/复制构造函数
- 为用户定义的类正确调用复制构造函数/赋值运算符
- 复制构造函数中的递归调用
- 编译器调用复制运算符而不是移动运算符
- 为什么我的运算符 + 重载尽管是通过引用传递的,但仍调用我的复制构造函数?
- 使用 pybind11 调用 Python 函数时避免复制输入数据
- 为什么没有调用此模板类的复制构造函数?
- 为什么当我做复制和交换习语时不调用我的复制构造函数?
- std::async 如何工作:为什么它会调用这么多次复制/移动?
- 调用类模板中隐式删除的复制构造函数
- 我不知道为什么复制构造函数的调用在 c++ 中不稳定
- push_back std::vector,则重复调用复制构造函数
- 减少复制构造函数调用
- 调用值构造函数而不是复制构造函数
- 向量<shared_ptr<X>>复制- 调用 X 构造函数?