簡體   English   中英

復制派生類的構造函數,更改基類

[英]copy constructor for derived class changing base class

假設我有以下情況:

class NamedObject{
public:
    NamedObject(const std::string &name):name_{std::move(name)}{}
private: 
    const std::string name_;
}

class Person: public NamedObject{
public:
    Person(const std::string &name, int age): NamedObject(name), age_{age}{}
private:
    int age_;
}

我想創建一個“復制構造函數”,在其中復制Person所有成員,但更改名稱(無論出於何種原因)。

class Person: public NamedObject{
public:
    Person(const std::string &name, int age): NamedObject(name), age_{age}{}
    Person(const std::string &newName, const Person &other): NamedObject(name){
        age_ = other.age;
    }
private:
    int age_;
}

現在假設我不僅具有age屬性,而且具有許多屬性,並且它們在開發過程中發生了很大變化。 是否可以輕松地創建類似Person(const std::string &newName, const Person &other)而無需手動復制age_ = other.age;等所有屬性age_ = other.age; 想法是,在開發過程中,如果添加新屬性,則不必總是記得要更改此構造函數。

請注意,我不能簡單地更改名稱,因為它是const

您可以在NamedObject上定義什么都不做的賦值運算符。 然后,您將可以在“復制構造函數”中使用*this = other

class NamedObject{
public:
    NamedObject(const std::string &name):name_{name}{}
    NamedObject &operator= (const NamedObject &) {
        return *this;
    }
    const std::string name_;
};


class Person: public NamedObject{
public:
    Person(const std::string &name, int age): NamedObject(name), age_{age}{}
    Person(const std::string &newName, const Person &other): NamedObject(newName){
        *this = other;
    }
    int age_;
};

實時示例: https//onlinegdb.com/rJ4J5oy3M

工作原理:

C ++將自動為符合條件的類定義一個副本分配運算符(請查看以下鏈接,詳細了解符合條件的含義)。 來自cppreference

如果隱式聲明的副本賦值運算符既不刪除也不瑣碎,則在使用odr時由編譯器定義(即生成並編譯函數體)。 對於聯合類型,隱式定義的副本分配會復制對象表示形式(如std :: memmove所示)。 對於非聯合類類型(類和結構),運算符使用標量的內置賦值和類類型的復制賦值運算符,按其初始化順序對對象的基礎和非靜態成員執行成員級的成員復制賦值。

因此,對於您的示例,隱式定義的副本賦值運算符(當我們執行*this = other;時調用的那個)將定義如下:

  • 它將使用NamedObject的復制賦值運算符復制基類(我們定義為不執行任何操作,因此不會復制name_ ),
  • 它將使用age_和您添加到該類中的任何其他成員的副本分配運算符。

暫無
暫無

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

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