c++ - 有没有一种方法可以交换成员变量而无需在子构造函数中单独传递它们?
问题描述
我的课程如下:
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;
}
我知道如果我重写ReturnX
,Derived
那么基指针将正确使用正确的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 成为可通过虚函数访问成员的接口
在这里,我们有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_) {}
};
当你使用它时,你不必x
在创建时指定一个值Derived
,它按预期工作:
int main() {
std::unique_ptr<Base> b = std::make_unique<Derived>();
// Prints 10
std::cout << b->getX() << '\n';
}
推荐阅读
- c# - 绑定 TreeView 子项绑定不起作用
- elasticsearch - Logstash 作为带有 JDBC 输入的服务
- html - 使用 !important 用 css 文件覆盖内联 CSS 不起作用
- javascript - Bootstrap 侧边栏 - 固定桌面和设备上的响应式覆盖
- java - 即使错误的 XML 根元素,Jackson 解组成功
- scala - 为什么这个简单的 quill 引用无法编译?
- r - 如何在 Bookdown 中编写伪代码
- c# - System.Net.WebClient 在将 DownloadString 与 Bloomberg Web 服务一起使用时获取 ConnectionReset
- python - 如何循环遍历熊猫数据框并在条件下修改值?
- mendix - 如何在 Mendix 中导入小部件包?