[英]C++ How to properly copy container(vector) of pointers?
有幾次我偶然發現了我有一個需要復制的指針容器的場景。
假設我們有以下類層次結構:
學生(基礎班)
StudentService
StudentService類有一個std::vector<Student*> students
字段和以下構造函數:
StudentService::StudentService(std::vector<Student*> students) {
// code
}
僅使用std::vector::operator=
運算符並編寫this->students = students
是不正確的,因為這只會復制指針地址,因此如果外部某人刪除了那些指向的對象指針,然后StudentService類將受到影響。
解決方案是循環遍歷students
參數中的每個指針並創建一個新的動態對象,如下所示:
for(int i = 0; i < students.size(); i++) {
this->students.at(i) = new Student(*students.at(i));
}
但即使這樣也不合適,因為它會創建ONLY Student對象。 我們知道學生可以是新生,索菲爾,初中或高級。 所以這是我的問題:這個問題的最佳解決方案是什么?
我想有一種方法是在每個Student類中放置一個私有枚舉字段,並有4個if-else語句檢查它是什么類型的Student,然后根據它創建一個新的動態對象:
for(int i = 0; i < students.size(); i++) {
if(students.at(i).getType() == FRESHMAN) {
this->students.at(i) = new Freshman(*students.at(i));
} else if(students.at(i).getType() == SOPHMORE) {
this->students.at(i) = new Sophmore(*students.at(i));
} else if {
// and so on...
}
}
但這仍然看起來很麻煩,你會建議什么?
你正在尋找克隆模式。 向Student添加clone()虛函數,在每個后代中重寫並創建相應的副本。 然后按照您正確指定的方式編寫容器的深層副本。
編輯:我的工作假設是你的新生等班級來自學生。 如果沒有,請使用變體<>並應用副本訪問者。
解決所有權問題
如果您希望在模塊之間共享Student
,那么您將面臨所有權問題,我建議使用std::shared_ptr<Student>
-s的向量來解決它。
如果你有一個std::vector<std::shared_ptr<Student>>
,你可以將它傳遞給任何你想要的人。 接收器可以使用賦值運算符復制vector
,稍后他添加/刪除的任何對象都不會影響原始容器,就像您希望的那樣。
解決克隆問題
如果您對每個具有自己的Student
-s向量副本的模塊感興趣,那么您將面臨克隆問題。
您可以通過向您的類添加以下方法來解決它:
class Student {
[..]
virtual Student * clone() const = 0; // Assuming Student is abstract, otherwise implement as well
};
class Freshman : public Student {
[..]
virtual Freshman * clone() const { return new Freshman(*this); }
};
// Same for other derived classes...
然后使用std::transform
復制向量:
// students is the original std::vector<Student *>
std::vector<Student *> copy(students.size());
std::transform(students.begin(), students.end(), copy.begin(), [](Student * s) -> Student * { return s->clone(); });
順便說一句,這是二年級學生,不是索菲爾......
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.