我有如下类(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::arrays
像x
并传递它们单独进入构造函数非常乏味。
最佳答案
方案一:根据派生类提供的策略构造基类成员
这里,基类由基类提供策略。该策略基本上只包含返回成员初始值的函数。
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/