Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/146.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ C+中成分关系的继承+;_C++_Inheritance_Composition - Fatal编程技术网

C++ C+中成分关系的继承+;

C++ C+中成分关系的继承+;,c++,inheritance,composition,C++,Inheritance,Composition,我经常面对这个问题。假设我有这些课程: class B { public: virtual std::string className(){return "B";} }; class A { public: A() : _B(new B) {} virtual std::string className(){return "A";} virtual void desc() { std::cout <<

我经常面对这个问题。假设我有这些课程:

class B
{
  public:
    virtual std::string className(){return "B";}
};

class A
{
  public:
    A()
    : _B(new B)
    {}

    virtual std::string className(){return "A";}

    virtual void desc()
    {
      std::cout << "I am " << className() << 
        " and I own: " << _B->className() << std::endl;
    }

  protected:
    B * _B;
};
但这显然是不好的,因为
SuperA
实际上会有两个
B
s:一个来自
A
类,另一个来自
super
类。而
desc
的覆盖也不是那么优雅

我可以看到,我可以在
A
中的
B*
上设置setter和getter,并在
SuperA
中覆盖它们,以使用
SuperB
而不是
B
,并且从不直接引用
B*
并始终使用getter,但这似乎对
A
有点干扰

尝试组合,即拥有
SuperA
拥有
A*
实例也不会更好

如果
A
拥有的不是一个
B*
,而是一个say
std::vector
,情况就更糟了


这是一个普遍的问题吗?有没有一个我看不到的优雅解决方案?

你只需要
A
有一个受保护的构造函数,它接受
B*

class A {
public:
    A()
    : _B(new B)
    { }

protected:
    A(B* b)
    : _B(b)
    { }
};
以便:

class SuperA : public A {
public:
    SuperA()
    : A(new SuperB)
    { }
};

为什么在
a
中不能有一个接受
B
指针的受保护的命令?然后使用它来构造
superA
A
子对象和
superA
?您可以在
superA
中使用
static\u cast
dynamic\u cast
。不是很优雅,但也许足够满足你的目的了?@StoryTeller这是一个解决方案。这对a来说有点侵入性。我认为解决这个问题的一种方法是类
a
SuperA
有两个职责:它们分别将
B
SuperB
适配到其他接口,并管理
B
SuperB
对象的生命周期。您可以通过只提供转换对象
A(B*)
等来分担这些责任,然后提供另一种类型来管理这些对象的生存期。@RedWark,可能是这样,但我认为这并不比一开始就有一个受保护的memeber更具侵入性。我没有想到这一点。这个解决方案实际上没有那么复杂,并且支持我在问题的后半部分中提到的向量!谢谢
class SuperA : public A {
public:
    SuperA()
    : A(new SuperB)
    { }
};