簡體   English   中英

C ++復制,移動,交換,賦值和析構函數的繼承? 我需要哪一個

[英]C++ Inheritance of copy, move, swap, assignment and destructor? Which do I need

假設我有兩個班

Base管理一些內存。 它具有工作移動,交換,分配和析構函數。 派生不添加任何需要管理的新內容(無需新的內存分配)。

class Base
{
public:
    Base();
    Base(const Base& other);
    friend void swap(Base& a, Base& b);
    Base(Base&& other);

protected:
    int** some2Darray;
    int w, h;
};

class Derived : public Base
{
public:
    Derived();
    //...?
};

我是否需要在派生類中實現所有這些功能才能變得更好? 如何重用基類中的那些函數? 我不需要在此類中管理更多的內存。

如果將成員添加到Derived類中,這些函數將如何顯示? 我應該完全重寫所有這些功能,還是應該使用某種方法來使用例如“復制”基類,並僅在復制構造函數中復制該添加的成員?

c++11 ,您可以繼承 (編輯:是的,這不是真正的繼承,也許應該明確指出)構造函數。 通過

class Derived : public Base
{
public:
    Derived();
    using Base::Base; // <-- this will import constructors
};

但這將無法解決任何額外費用!

但是,您不需要復制代碼。 您可以只調用父函數。

例如:

class Derived : public Base
{
   int extra;
public:
   Derived() : Base(), extra(42){};
   Derived(const Derived& other) : Base(other) {extra = other.extra;};
   void copy(const Derived& other);
   friend void swap(Derived& a, Derived& b);
};

void Derived::copy(const Derived& other){
   Base::copy(other);
   extra = other.extra;
}

也不要忘記虛擬析構函數。

編輯:對於交換,我只是將派生實例轉換為它們的基礎,以使編譯器使用為父類型定義的交換。 然后交換多余的東西。

void swap(Derived& a, Derived& b){
    swap(static_cast<Base&>(a), static_cast<Base&>(b));
    swap(a.extra, b.extra);
}

首先: 繼承構造函數,賦值運算符和析構函數(*)。 相反,在某些情況下,編譯器可能會自動為您合成它們。

所以,當需要給他們寫? 僅當default生成的版本與您的需求不符時:

  • 可訪問性不是您想要的(它始終是public
  • 該方法應delete d
  • default行為不正確(例如,淺拷貝)
  • 編譯器無法為您合成方法

關於后兩點:

  • “三則規則”指出,如果您編寫了復制構造函數,復制分配運算符或析構函數中的任何一個,則該規則應為: 您還應該提供其他兩個
  • 在C ++ 11中,如果您編寫這3種特殊方法中的任何一種,則不會自動合成Move Constructor和Move Assignment Operator
  • 在C ++ 11中,如果編寫了Move構造函數或Move賦值運算符,則這3種特殊方法都不會自動合成

(*)稱為繼承構造函數的C ++ 11功能不良而得名,它比繼承更多的放權


話雖如此,如果“ Derived ”沒有任何棘手的屬性,那么您可以避免編寫那些成員。 如果仍然希望編寫它們(例如,避免內聯),則應該可以使用= default語法:

// Derived.h
class Derived: public Base {
public:
    Derived(Derived const&) = default;
    Derived& operator(Derived const&);
};

// Derived.cpp
Derived& Derived::operator=(Derived const&) = default;

我不確定move運算符,但是您不必實現copy ctor,destructor和copy運算符,因為標准函數會自動從所有基類中調用相應的函數。

編輯:另請參見如何在C ++中使用基類的構造函數和賦值運算符?

暫無
暫無

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

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