c++ - 在 C++ 中,对象可以与其基对象共享相同的多态成员吗?
问题描述
我有以下问题,我真的无法在标题中的一个句子中很好地描述。
我有一个简化的类层次结构,我无法更改
class Base {
protected:
std::vector<int> a_;
public:
virtual ~Base() = default;
Base(std::vector<int> a): a_(std::move(a)) {}
virtual void do_stuff() { /*modify a_*/ }
};
class Derived: public Base {
protected:
std::vector<int> b_;
public:
Derived(std::vector<int> a, std::vector<int> b): Base(std::move(a)), b_(std::move(b)) {}
void do_stuff() override {
Base::do_stuff();
/*modify b_*/
}
};
我需要向这个层次结构添加一些功能,所以我创建了一个“扩展”层次结构:
class BaseExtended {
private:
Base underlying_;
int x_;
public:
virtual ~BaseExtended() = default;
BeseExtended(std::vector<int> a, int x): underlying_(std::move(a)), x_(x) {}
virtual void do_more() {
underlying_.do_stuff();
/* do more stuff according to x_ */
}
};
class DerivedExtended: public BaseExtended{
private:
Derived underlying_;
int y_;
public:
DerivedExtended(std::vector<int> a, int x, std::vector<int> b, int y)
:BaseExtended(std::move(a), x), underlying_(std::move(b)), y_(y) {}
void do_more() override {
BaseExtended::do_more();
underlying_.do_stuff();
/* do more stuff according to y_ */
}
};
但这并没有做我想要的,在我调用后只存储了两个向量v1和v2
std::shared_ptr<BaseExtended> de = new DerivedExtended(v1, 1, v2, 2);
我不知道这是否可以在不修改原始类的情况下实现,尤其是如何在DerivedExtended中仅存储一个 vector v1副本。这可以做到吗?
解决方案
解决此问题的一种方法是动态分配underlying_
并具有BaseExtended
派生protected
类的构造函数,该构造函数Base*
接受underlying_
.
像这样的东西:
class BaseExtended {
...
protected:
std::unique_ptr<Base> underlying_;
BeseExtended(int x, std::unique_ptr<Base> underlying): underlying_(std::move(underlying)), x_(x) {}
...
};
class DerivedExtended: public BaseExtended {
...
public:
DerivedExtended(std::vector<int> a, int x, std::vector<int> b, int y) :
:BaseExtended(std::make_unique<Derived>(std::move(a), std::move(b)), x), y_(y) {}
然后您可以访问(underlying_
因为BaseExtended
现在是protected
)。
这将防止a_
创建多个版本,并且在某种程度上简化了孩子的代码,这是双赢的!
请注意,您必须小心,但是,当您调用in时do_stuff()
,您可能希望明确调用( ) ,否则如果覆盖则它将被调用两次(并且不会被调用)。underlying_
BaseExtended
Base::do_stuff()
underlying_->Base::do_suff()
Derived
do_stuff()
DerivedExtended::do_more()
Base::do_stuff()
推荐阅读
- c++ - 尝试使用算术运算符防止隐式转换
- c++ - 在 Mac 上提升 python
- java - 为 Java 调试一个简单的控制台游戏
- azure - 云外壳中的 azcopy 尝试将源存储帐户内容复制到目标存储帐户失败
- postgresql - 努力手动创建与 gorm / migrate 的关系
- javascript - JavaScript + HTML:将文本打印到 HTML 段落元素时出现问题
- python - 使用自定义 PDF 生成随机值
- xml - 使用 powershell 更新具有布尔值的 xml 属性
- javascript - 循环遍历数字数组构造索引节点对象
- pandas - Pandas - 在同一标题中使用多个标签来透视和重新排列表