[英]Copying class by constructor in C++
我有一个 class 人,其中包括姓名、ID 和 static 构造函数。 我定义了一个复制构造函数,它只将名称复制到定义人员。 有谁知道为什么定义 per_2 后 ID 和 counter 没有正确显示? 我是否必须以某种方式定义 ID 以使其异常且无法复制?
#include<iostream>
#include<string>
using namespace std;
class person {
public:
string name;
int ID;
static int counter;
person();
~person();
person(const person & );
};
int person::counter = 0;
person::person() {
counter++;
ID = counter;
}
person::~person() {
}
person::person(const person & obj) {
this - > name = obj.name; //Here I define that only name is supposed to be copied
}
int main() {
person per_1;
per_1.name = "John";
cout << per_1.ID << endl; // It gives 1 and it's fine.
cout << person::counter << endl; // So does it.
person per_2 = per_1; // Here I copy class and give per_1's variables to per_2.
cout << per_2.ID << endl; // Here I expect 2, because constructor incremented counter and assigned it to per_2.ID while it gives -84534283.
cout << person::counter << endl; // There is still 1, despite incrementing counter in constructor.
system("Pause");
return 0;
}
使用复制构造函数时不会调用默认构造函数,但您可以添加一个转换构造函数,该构造函数根据name
创建person
并委托给其他构造函数中的该构造函数。 我建议delete
复制构造函数并将其替换为default
的移动构造函数。 您可能不希望两个person
具有相同的 ID。
例子:
#include <iostream>
class person {
public:
int ID;
std::string name;
static int counter;
person(); // default ctor
explicit person(const std::string&); // converting ctor
person(const person &) = delete; // copy ctor deleted to not get two persons
// with the same ID
person(person&&) = default; // move ctor
};
int person::counter = 0;
person::person() :
person("") // delegate
{}
person::person(const std::string& Name) : // colon starts the member initializer list
ID(++counter),
name(Name)
{}
您可以使用 name 的默认值将单独的默认构造函数和转换构造函数替换为一个构造函数:
person(const std::string& Name = {}) :
ID(++counter),
name(Name)
{}
调用复制构造函数时不执行默认构造函数。 因此, ID
未在per_2
中初始化。
您需要从默认构造函数复制代码以分配下一个可用 ID(或添加私有成员 function 来执行此操作,并让两个构造函数都调用它)。
当您调用复制构造函数时,默认构造函数将被忽略。 个人 ID 和person::counter
都只由默认构造函数更改,因此这意味着在调用复制构造函数时它们将被忽略。 您的程序正在为 per_2 的名称和 ID 分配 memory,它们以虚拟值开头,然后将名称覆盖为 per_1 名称的副本,然后就完成了。 在您的复制构造函数中,您还需要指定 ID 应该是什么以及person::counter
或不进行任何更改。 如果您愿意,您可以将这两个功能添加到由默认构造函数和复制构造函数调用的辅助方法中,以获得更简洁的代码。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.