簡體   English   中英

從基類調用復制和賦值運算符以在 C++ 中創建繼承的類實例

[英]Calling copy and assignment operators from base class to create inherited class instances in C++

我有以下課程(例如):

class A {

   public:
   A(void) : i(0) {}
   A(int val) : i(val) {} 
   A(const A& other) : i(other.i) {}
   A& operator=(const A& other) {
       i = other.i;
       return *this;
   }

   int i;
};

class B : public A {

   public:
   B(void) : A(), j(0) {};
   B(const B& other) : A(other), j(other.j) {}
   B(int i, int j) : A(other.i), j(other.j) {}
   B& operator=(const B& other) {
      A::operator=(other);
      j = other.j;
      return *this;
   }
   
   int j;
};

我的問題是,給定B中的operator=重載和復制構造函數,如果我希望能夠從A的已初始化實例中創建B的實例,或者將A的現有實例分配給B的現有實例,會不會有必要在Boperator=上使用以下簽名定義另一個復制構造函數?:

B(const A& other);
B& operator=(const A& other);

目標是能夠僅使用基類信息實例化/分配派生類實例。
PS:我在 C++98 中工作,無法使用任何更新的標准。

目標是能夠僅使用基類信息實例化/分配派生類實例。

你的目標對我來說聽起來很可疑。

通常在實踐中,您有兩種不同的情況:

  • 數據對象(不需要繼承層次結構)
  • 行為對象(通過繼承實現相同的接口)。

數據對象(因為它們沒有公共基類)實現實例化和賦值(復制構造函數和賦值運算符)。

行為對象(類層次結構中的對象)不能以通用方式實現基類對象的賦值(您將如何處理派生類中存在但基類中不存在的成員變量?給它們一個默認值?讓它們保持不變? )。

也就是說,您應該使用與復制構造函數和賦值不同的 API,以避免混淆和隱式強制轉換。

也就是說,如果你有兩個:

B& operator=(const B&);
B& operator=(const A&);

那么當代碼從 B 實例分配時這是不明確的(因為編譯器可以調用它們中的任何一個)。

您可以添加一個B::copy_common_values(const A&); . 這也會使其更加明確。

如果您正在嘗試解決 xy 問題,還請查看原型設計模式。

是的,你必須定義類似的東西。

B(常量 A& 其他);

這將允許從A構造B 這也將允許通過將A隱式轉換為B然后進行分配來將A分配給B 因此,僅此一項就足夠了。 但是你會得到一個額外的副本。

B& operator=(const A& other);

這使得將A分配給B更有效,因為您避免了臨時B的額外副本。 這也應該允許分配可以隱式轉換為A東西,例如:

B b = 1;

如果您不希望這樣,您可能必須添加一些explicit的 . C++98 有明確的嗎? 那是上個千年。

注意:在現代 C++ 中,由於復制省略以及您可以使用移動語義和完美轉發引用,這會更有效。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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