【问题标题】:C++: For a class that inherited multiple classes, how to inherit certain attributes from one class and others from the other?C++:对于一个继承了多个类的类,如何从一个类继承某些属性而从另一个类继承其他属性?
【发布时间】:2019-07-19 05:16:21
【问题描述】:

谁能帮我理解从多个类继承的类如何保留一个类的某些属性值和另一个类的其他某些属性值。

(以及如何为某些功能这样做)


这里有一段代码来描述这个问题。

是有菱形继承结构的情况:


------------- 基础

---------/----------------\

-------/--------\

--- 母亲-------------父亲

---\ -----------------------/

-----\ ------------------/

---------\ -------------/

------------ 孩子


目标是继承自 Father 类和 Mother 类(显然来自 Base 类),但保留 Fathery 值和 z 值来自Mother。我只是不知道该怎么做。

我认为以下代码的问题在于调用构造函数的顺序使得 Father 构造函数在 Mother 构造函数初始化之前覆盖了 z 值。

我在想我可能必须创建一个特殊的 private/protected Father 构造函数,它不会初始化 z 和一个特殊的 private/protected Mother 构造函数不会初始化 y 并显式调用这些构造函数。

但是如果这是正确的方法或者是否有更好的方法,我想知道。有人知道更好的方法吗?


#include <iostream>

class Base {

    protected:

        int x;
        int y;
        int z;

    public:

        Base(void) : x(0) {}

};

/* — — — — — — — — — — — — — — — — — — — —  */

class Father
    : public virtual Base {

    public:

        Father(void) : Base() {
            y = 1;
            z = 1;
        }
};

/* — — — — — — — — — — — — — — — — — — — —  */

class Mother
    : public virtual Base {

    public:

        Mother(void) : Base() {
            y = 2;
            z = 2;
        }
};

/* — — — — — — — — — — — — — — — — — — — —  */

class Child
    : public Mother, public Father {

    public:

        Child(void) : Base() {

            y = Father::y;
            z = Mother::z;
        }

        int getX() { return x; };
        int getY() { return y; };
        int getZ() { return z; };
};

/* — — — — — — — — — — — — — — — — — — — —  */

int main() {

    Child newborn;

    std::cout << newborn.getX() << std::endl
              << newborn.getY() << std::endl
              << newborn.getZ() << std::endl;

    return (0);
}

/* — — — — — — — — — — — — — — — — — — — —  */


Output:

0
1
1

——— VS ———

Desired Output:

0
1
2

【问题讨论】:

  • en.wikipedia.org/wiki/XY_problem 我看不出你要解决什么问题。
  • 你就是不这样做。如果您想要的只是值,那么您可以继承其他两个类中的基本值并设置静态值作为默认值。如果您需要更多的东西,那么我认为您需要向我们展示您的现实问题。
  • 在纸上、在学校和书本上,多重继承和嵌套继承的具体类看起来很有吸引力。在实践中,很难做到正确且难以维护。接口继承可能是一件很棒的事情,但是对于具体的类,我倾向于建议按照“has a”而不是“is a”来设计。
  • Aymen,Paddy 可能要去的地方是Liskov Substitution Principle,它基本上归结为不继承它没有意义的地方。继承建立一个is-a relationship。孩子是妈妈。这没有多大意义。孩子是父亲。这也没有多大意义。孩子同时做母亲和父亲是没有意义的。你可以肯定,但你也可以int x= x;int *x = null; *x = 42; 仅仅因为你能做到并不意味着你应该这样做。
  • 您继承了基类可继承的所有内容。你无法选择。

标签: c++ multiple-inheritance c++98 diamond-problem


【解决方案1】:

你不能这样做。

virtual inheritance 旨在不重复成员。

知道这一点:

  • Child::xMother::xFather::x完全是同一个变量
  • Child::yMother::yFather::y完全是同一个变量
  • Child::zMother::zFather::z完全是同一个变量

这些只是访问内存堆栈上相同变量的三种方式。所以当你写y = Father::y;时,它与你写y = y;时完全一样,以此类推。


如果你真的想在不改变设计的情况下这样做,也许你可以在FatherMother 中存储一个包含你想要的预设的额外变量,然后将其提供给@ 987654335@ 通过范围分辨率

FatherMotherChild 可能看起来像:

class Father : public virtual Base
{
    protected:
        int preset;

    public:
        Father() : preset(1)
        {
            y = preset;
            z = preset;
        }
};

class Mother : public virtual Base
{
    protected:
        int preset;

    public:
        Mother() : preset(2)
        {
            y = preset;
            z = preset;
        }
};

class Child : public Mother, public Father
{
    public:
        Child()
        {
            y = Father::preset;
            z = Mother::preset;
        }

        int getX() const {return x;}
        int getY() const {return y;}
        int getZ() const {return z;}
};

它应该做一些改变。


最后,我想说,对于每个需要多重继承的问题,至少有一个其他解决方案(更好的设计)并不意味着多重继承(这只是我的看法)。

因此,我建议您重新考虑您的设计,而不是使用我在此处提出的解决方法。

【讨论】:

  • 我需要这样做,因为我有约束要遵循我需要的地方,同时只创建一次基类,仍然使用来自特定父级的值。谢谢。经典的“钻石问题”继承。
猜你喜欢
  • 1970-01-01
  • 2021-09-03
  • 2014-04-14
  • 2019-05-13
  • 2023-03-09
  • 2018-05-05
  • 1970-01-01
  • 1970-01-01
  • 2020-12-26
相关资源
最近更新 更多