簡體   English   中英

有沒有一種方法可以換出成員變量而無需在子構造函數中單獨傳遞它們?

[英]Is there a way I can swap out member variables without passing them individually in a child constructor?

我有以下課程:

class Base
{
    public:
        virtual int ReturnX()
        {
            return x;
        }

    private:
        int x = 5;
};

class Derived : public Base
{
    private:
        int x = 10;
};

和代碼如下:

int main()
{
    std::unique_ptr<Base> b = std::make_unique<Derived>();

    std::cout << b->ReturnX() << std::endl;
}

我了解,如果我在Derived重寫ReturnX ,則基本指針將正確使用正確的ReturnX但是如何使用正確的x值獲取它呢? 我希望這條線返回10。

我不想僅在構造函數中傳遞它的原因是,我有很多(10+)多維x std::arraysx一樣,將它們分別傳遞到構造函數中非常繁瑣。

解決方案1:根據派生類提供的策略構造基類成員

在此,基類由基類提供策略。 該策略基本上只包含返回成員初始值應為的函數。

class Base {
    int x;
    std::string y;
   public:
    struct DefaultPolicy {
        int getX() { 
            return 5;
        }
        std::string getY() {
            return "Hello"; 
        }
    }; 

    virtual int getX() {
        return x;
    }
    virtual std::string getY() {
        return y;
    }

    template<class Policy>
    Base(Policy&& p) 
      : x(p.getX())
      , y(p.getY())
    {}

    // By default, Base uses the DefaultPolicy
    Base() : Base(DefaultPolicy()) {}

    virtual~Base() = default; 
};

現在,我們可以編寫一個使用給定策略的派生類:

class Derived : public Base {
    // This is our policy
    struct Policy {
        int getX() {
            return 10; 
        }
        std::string getY() {
            return "Hello, world!"; 
        }
    };

   public:
    Derived() : Base(Policy()) {}
};

解決方案2:建立一個具有通過虛擬功能訪問成員的接口

在這里,我們將Base作為一個沒有成員變量的抽象類:

class Base {
   protected:
    virtual int& x_() = 0; 
   public:
    virtual int getX() {
        return x_();
    }

    virtual ~Base() = default; 
};

然后,我們可以基於初始值和其他內容創建單獨的派生類:

class Derived1 : Base {
    int x = 5;
   protected:
    int& x_() override {
        return x;
    }
};
class Derived2 : Base {
    int x = 10;
   protected:
    int& x_() override {
        return x;
    }
};

解決方案3:使用默認的構造函數參數

可以做這樣的事情嗎?

class Base {
   protected:
    int x;
   public:    
    Base(int x_ = 5) : x(x_) {}

    virtual int getX() {
        return x;
    }
    virtual ~Base() = default; 
};

class Derived : public Base {
   public:
    Derived(int x_ = 10) : Base(x_) {}
};

使用它時,在創建Derived時不必為x指定值,並且可以按預期工作:

int main() {
    std::unique_ptr<Base> b = std::make_unique<Derived>();

    // Prints 10
    std::cout << b->getX() << '\n';
}

暫無
暫無

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

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