簡體   English   中英

C ++如何正確復制指針的容器(向量)?

[英]C++ How to properly copy container(vector) of pointers?

有幾次我偶然發現了我有一個需要復制的指針容器的場景。

假設我們有以下類層次結構:

  • 學生(基礎班)

    • 新生(子類)
    • Sophmore(子類)
    • 少年(子類)
    • 高級(子類)
  • 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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM