在 C++ 中通过构造函数复制类
Posted
技术标签:
【中文标题】在 C++ 中通过构造函数复制类【英文标题】:Copying class by constructor in C++ 【发布时间】:2020-04-05 22:41:04 【问题描述】:我有一个班级人员,包括姓名、ID 和静态构造函数。我定义了一个复制构造函数,它只将名称复制到定义人员。有谁知道为什么定义 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;
【问题讨论】:
@Marcios216 此问题仍列为未解决。没有任何答案有助于解决您遇到的问题吗? 【参考方案1】:当您使用复制构造函数时,不会调用默认构造函数,但您可以添加一个转换构造函数,该构造函数从 name
创建一个 person
并在其他构造函数中委托给该构造函数。我建议 delete
ing 复制构造函数并将其替换为 default
移动构造函数。您可能不希望两个具有相同 ID 的 person
s。
例子:
#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)
您可以通过使用名称的默认值将单独的默认构造函数和转换构造函数替换为一个构造函数:
person(const std::string& Name = ) :
ID(++counter),
name(Name)
【讨论】:
【参考方案2】:调用复制构造函数时不执行默认构造函数。因此,ID
未在 per_2
中初始化。
您需要从默认构造函数复制代码以分配下一个可用 ID(或添加一个私有成员函数来执行此操作,并让两个构造函数都调用它)。
【讨论】:
也许提到委托构造函数? 也许听起来很蠢,但是如果我先初始化 per_2(应该执行默认构造函数)然后在下一行写 per_2=per_1 呢? @Macios216 由于您尚未定义复制赋值运算符,因此将使用默认值,它将覆盖ID
。【参考方案3】:
当您调用复制构造函数时,默认构造函数将被忽略。个人 ID 和 person::counter
都仅由默认构造函数更改,因此这意味着在调用复制构造函数时它们将被忽略。您的程序正在为 per_2 的名称和 ID 分配内存,它们以虚拟值开头,然后将名称覆盖为 per_1 名称的副本,然后就完成了。在您的复制构造函数中,您还需要指定 ID 应该是什么以及person::counter
,否则将不会进行任何更改。如果您愿意,您可以将这两个功能添加到由默认构造函数和复制构造函数调用的辅助方法中,以获得更简洁的代码。
【讨论】:
以上是关于在 C++ 中通过构造函数复制类的主要内容,如果未能解决你的问题,请参考以下文章