1

是否有必要实例化另一个类的派生类?
如果我不这样做,我无论如何都可以访问它的方法,就像在这个例子中一样:

#include <iostream>
struct Class1 {
public:
    void func();
};

struct Class2 : public Class1 {
    // Class1 c1; <-- is this necessary?
};

void Class1::func(){
    std::cout << "function called" << std::endl;
}
int main() {
    Class2 c2;
    c2.func();
}

我得到了预期function called
但在某些示例中,我看到基类在派生类中被实例化:Class1 c1;. 它是干什么用的?

4

4 回答 4

2

是否有必要实例化另一个类的派生类?

不,绝对没有必要。

但在某些示例中,我看到基类在派生类中被实例化:Class1 c1;. 它是干什么用的?

在不知道这些示例具体处理什么的情况下——即这些类的语义是什么——以有意义的方式解释它们并不容易。但是,当您创建某种类型的数据成员时,您的对象具有该类型的子对象。所以当你这样做时:

struct Y { };

struct X
{
    int a;
    std::string b;
    Y c;
};

每个类型X的对象都会有一个a类型int的子对象、一个b类型的子对象b和一个c类型的子对象Y。您将使用点符号访问它,如下所示:

Y foo();

X x;
std::cout << x.a;
x.b = "Hello, World!";
X.c = foo();

类似地,当一个类D派生自基类B时,它包含一个类型的子对象B,并隐式继承 的所有数据成员B

struct B
{
    int a;
    std::string b;
};

struct D : B
{
    bool c;
};

// ...

D d;
d.c = true;
d.b = "Hello, Base Class!";
d.a = 42;

现在在您的情况下,Class2除了派生类之外,该类Class1还具有 type 的数据成员Class1。注意,这个数据成员不是的基础子对象Class2,而是一个附加的成员子对象。那么这是什么意思?

对此持保留态度,但为了培养直觉,您可以认为继承模拟“IS-A”关系,而数据成员关系模拟“HAS-A”关系。

因此,Class2从模型中公开派生Class1出“所有Class2对象都是Class1对象”这一事实,因此继承了所有Class1的数据成员。这就解释了为什么 type 的对象Class2有一个 type 的基本子对象Class1

另一方面,Class2具有类型数据成员Class1的事实模拟了“所有Class2对象都包含/嵌入/拥有类型对象”的事实Class1。这就解释了为什么 type 的对象Class2有一个 type 的成员子对象Class1

现在,在您提到的示例的特定情况下,上述两个语义都是同时建模的——即Class2同时是 IS-A 和 HAS-A——Class1但这绝不是必要的。不是每个thingyIS-Awidget也有 HAS-A widget

我希望这以抽象的方式对您有意义。设计是否正确主要取决于您Class1Class2对象的语义,以及它们要建模的内容,但信息是:

如果Class2派生自Class1,则不会强制您将Class1数据成员添加到Class2.

于 2013-05-13T22:34:26.937 回答
0

在这种情况下,派生类中不需要有基类成员变量。多态性也仅适用于指针和引用类型。

于 2013-05-13T22:33:35.350 回答
0

不,没有必要。

class Base {

}

class Derived : public Base {

}

该类Derived将继承该类的成员Base

于 2013-05-13T22:33:53.987 回答
0

这绝对没有必要。如果没有看到您所指的示例,很难说出作者为什么会创建该实例。最有可能的是显示当 Class2::func() 调用 c1.func() 时会发生什么。

于 2013-05-13T22:35:54.580 回答