[英]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.