c++ - 有没有办法让派生实例使用现有的基础实例
问题描述
对于类层次结构,例如:
struct base { int i = 1; };
struct derived final : public base
{
int j = 2;
void f() { i = 2; }
};
// more derivations from base
我想要一种创建实例derived
但使用现有base
实例的方法。例如:
base b; // b.i == 1
{
derived d;
d.f(); // d.i == 2
}
有没有办法进行设置,以便在调用d.f()
值为b.i
2 之后?正如我试图指出的那样,生命周期derived
相当短。
从概念上讲,我想让base
看起来像derived
一会儿,“看起来像”意味着访问d.j
. 完成后,我希望对 to 所做的更改d.i
“坚持” b.i
。成员变量的明显解决方案base& b
不起作用,因为访问i
需要不同的语法:b.i
而不是i
.
将实例复制derived
回base
我完成时会起作用;但这似乎很臭。
{
derived d;
d.f(); // d.i == 2
b = d; // copy, YUCK!
}
但我真的只想要并且需要一个base
.
实际发生的是我正在尝试模拟嵌套函数;但我不想更改语法以访问i
或j
。
在伪代码中,我想做类似的事情:
struct s final
{
int i = 1;
void f()
{
int j = 2;
auto g = [&]();
}
// ... other code ...
void f::g() { i = 10; j = 20; }
};
换句话说,“本地函数”的实际代码远离它的声明位置。
解决方案
我看不出有任何方法可以与用作装饰器/视图的不同对象共享对象的相同成员变量,因为不同的对象b
具有不同的成员变量值集。d
b
如果derived
派生自base
,则base
-object 是每个derived
-object 的一部分,并且您不能在derived
不破坏固有base
-object 的情况下销毁 -object。
如果derived
不是从 派生的base
,那么您不能用代码base
中的类型对象替换期望 -object 的变量derived
;xxx.i
你的代码中的any要么xxx
作为 type 的对象,base
要么作为 typexxx
的对象derived
,但不能同时适用。因此,将包含xxx.i
的对象derived
和对象的通用代码应用于base
将不起作用(除非您有一个宏#define impl_f(b) { (b).i = 2; }
,但我不认为您认为 makros 形式的可重用代码)。
我能想到的一种方法是派生类,它强制使用 -object 进行初始化,并在销毁base
后将(更改的)值复制回该基对象:derived
struct base {
int i = 1;
base() { }
base(base &_b) { i = _b.i; }
};
struct derived_base : public base
{
derived_base(base &_b) : base(_b), b(_b) { }
~derived_base() { b = *this; }
private:
base &b;
};
struct derived1 final : public derived_base
{
int j = 2;
derived1(base &_b) : derived_base(_b) { }
void f() { i = 2; }
};
int main() {
base b; // b.i == 1
cout << "b member i (should be 1):" << b.i << std::endl;
{
derived1 d(b);
cout << "initially, d member i should be the value of b.i, i.e. 1:" << d.i << std::endl;
d.f(); // d.i == 2
cout << "after f(), d member i (should be 2):" << d.i << std::endl;
}
cout << "lifetime of d ended; b has overtaken the values from d" << std::endl;
cout << "b member i (should now be 2, too):" << b.i << std::endl;
}
推荐阅读
- firebase - 我可以使用 firebase 来实现登录和身份验证,但仍然使用 Docker 部署项目吗
- jquery - Uncaught (in promise) TypeError: Cannot read property 'template' of null popover.js
- join - 连接配置单元中的多个表时表别名无效
- javascript - 如何在继承的类中调用基方法?
- docker - 通过 Jenkins 作业从运行在 kubernetes pod 中的 docker 容器运行 bash 脚本
- r - 使用 gganimate 制作伯努利分布的动画,并在 p = 0.5 处意外跳跃
- nginx - NGINX 上的重定向 URI
- c# - 作为启动配置过程的一部分,您如何发送电子邮件?
- c++ - Boost ASIO ip tcp iostream expires_from_now doesn't result in an error when connection fails
- jquery - 将嵌套表单字段填充到下拉列表中