c++ - 有没有一种方法可以换出成员变量而不用在子构造函数中单独传递它们?

标签 c++ class virtual

我有如下类(class):

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+)多维std::arraysx并传递它们单独进入构造函数非常乏味。

最佳答案

方案一:根据派生类提供的策略构造基类成员

这里,基类由基类提供策略。该策略基本上只包含返回成员初始值的函数。

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 成为可通过虚函数访问成员的接口(interface)

在这里,我们将 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';
}

关于c++ - 有没有一种方法可以换出成员变量而不用在子构造函数中单独传递它们?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57227402/

相关文章:

c# - 如何在 C# 中浏览本地虚拟文件夹?

c++ - 让应用程序拥有 CPU 和 GPU 计算后端的最佳方式是什么

java - java中使用(Class)对象会恢复对象吗?

java - 在模型更改时更新虚拟 TableViewer 的条目

java - Java中从主类向其他类传递值

ruby - 是否可以为子模块赋予与顶级类相同的名称?

c++ - 从函数返回通用类型数据

c++ - 如何在不影响内部选项卡/小部件的情况下设置 QTabWidget 的样式?

c++ - 如果列表为空,QList::first() 会返回什么?

c++ - C++ 中的五角大楼项目