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