gpt4 book ai didi

c++ - 限制 C++ 中虚拟基类的对象共享

转载 作者:搜寻专家 更新时间:2023-10-31 02:22:53 25 4
gpt4 key购买 nike

我了解 C++ 中的物理和虚拟继承。但是,我想知道这个模型是否可以通过任何设计模式或技巧以某种方式实现。

不应修改类 E 和 F 以及它们的基类。假设它们来自外部库。

E 和 F 下面的所有内容都是开放的。可以引入中间帮助类、非成员函数、模板……所有可以实现这一点的东西:

           BaseClass
/ \
/ \
A A
/ \ / \
/ \ / \
B C B D
\ / \ /
\ / \ /
E F
\ /
\ /
\ /
FinalClass

请注意,E 和 F 不应共享一个 A。FinalClass 确实应该包含 2 个 A。我的问题是,创建 E 或 F 需要 B、C 和 D 虚拟继承 A。但是,如果 A 是虚拟基类,那么编译器只会在 FinalClass 中创建一个 A 对象,而不是两个不同的对象

所以,我想你们中的许多人会在这里推荐组合而不是继承。但是,组合在这里建模的是“有一个”关系,而不是“是一个”关系。在解释中,我希望 FinalClass 的行为真正像 E 或 F,包括能够将其转换为这些类。

最佳答案

这种布局在 C++ 中是不可行的,即使有额外的帮助类。

事实上,B 继承自 A,并且您想一方面与 C 共享 A 继承权,另一方面与 D 共享 A 继承权,这需要 B、C 和 D 虚拟地继承自 A。但是 A 将被共享跨越你钻石的两个分支。

备选方案

还有什么替代方案?

  • 如果您设法打破钻石左右分支之间 A 的共享,您也会打破公共(public)基础的共享。

  • 如果您要引入一些中间类 A1、A2 来在您的分支中实现左右共享,您会被 B 必须继承一个或另一个这一事实所困扰

  • 唯一的出路可能是为 B 设置一个重复的类。

最后一个解决方案不满足您的要求,但看起来如下:

struct Base { int x; };
struct A : public virtual Base { int a; };
struct AC : public A{}; // synonym
struct B : public virtual A { int b; };
struct BC : public virtual AC { int b; }; // !! clone !!
struct C : public virtual AC { int c; };
struct D : public virtual A { int d; };
struct E : public BC, C { int e; };
struct F : public B, D { int f; };
struct Final : public E, F { };

这里是对成员的访问:

Final f;
f.x = 2; // unambiguous: there's onely one of it
f.f = 1;
f.e = 2;
f.d = 3;
f.c = 4;
//f.b = 5; // ambiguous: there are two of it
f.E::b = 5; // successful desambiguation
f.F::b = 6; // successfuldesambiguation
//f.a = 7; // ambiguous: there are two of it
f.E::a = 7; // successful desambiguation
f.F::a = 8; // successful desambiguation

回到你的问题陈述:你说你不能干预 E 和 F 以上。在这种情况下你的选择非常有限:

  • 您公开继承
  • 你通过一些中间类私有(private)继承

但共享的效果是一样的,如下代码演示(在上面的代码之上):

class FI : private F  // make F private
{ public:
void set_xa(int u, int v) { x = u; a= v; }
void show_xa() { cout << "x:" << x << " a:" << a << endl; }
};
class EI : private E // make E private
{
public:
void set_xa(int u, int v) { x = u; a = v; }
void show_xa() { cout << "x:" << x << " a:" << a << endl; }
};

struct Final3 : public EI, public FI { };

Final3 h;
h.EI::set_xa(3, 4);
h.FI::set_xa(5, 6);
h.EI::show_xa();
h.FI::show_xa();
// the shared virtually inherited memebers are still shared !

结论:

通过继承,您将完全受限于 E 和 F 之上的设计,您无法对其施加影响。

所以第一个问题是:

  • 毕竟你不能改变这个设计(即克隆一个 B)吗?
  • 在两个分支之间设置 A shered 是不是不能接受(毕竟可能有正当理由)?

如果您对这两个问题的回答是否定的,您将不得不进行组合,并实现一种 proxy design pattern ,其中您的组合对象是您的两个组件的代理。

关于c++ - 限制 C++ 中虚拟基类的对象共享,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29863672/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com