是否有必要实例化另一个类的派生类?
不,绝对没有必要。
但在某些示例中,我看到基类在派生类中被实例化: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
但这绝不是必要的。不是每个thingy
IS-Awidget
也有 HAS-A widget
。
我希望这以抽象的方式对您有意义。设计是否正确主要取决于您Class1
和Class2
对象的语义,以及它们要建模的内容,但信息是:
如果Class2
派生自Class1
,则不会强制您将Class1
数据成员添加到Class2
.