当我在 C++ 中派生一个类时,它是不是会创建一个基类对象并将其作为我的成员变量存储在派生类中?

Posted

技术标签:

【中文标题】当我在 C++ 中派生一个类时,它是不是会创建一个基类对象并将其作为我的成员变量存储在派生类中?【英文标题】:When I derive a class in C++, does it create an object of base class and store it as my member variable in derived class?当我在 C++ 中派生一个类时,它是否会创建一个基类对象并将其作为我的成员变量存储在派生类中? 【发布时间】:2010-08-17 22:05:25 【问题描述】:

假设我创建了一个如下的派生类,

    class CHIProjectData : public QObject 
 
CHIProjectData(QMap<QString,QString> aProjectData,
                           CHIMetaData* apMetaData = 0,
                           QObject* parent = 0); 
    private:
            QMap<QString,QString> m_strProjectData;
            CHIAkmMetaData* m_pMetaData; 
;

我实现了,

CHIProjectData::CHIProjectData(QMap<QString,QString> aProjectData,
                               CHIMetaData* apMetaData,
                               QObject* aParent)
    :m_strProjectData(aProjectData),
    m_pMetaData(apMetaData),
    QObject(aParent)



我知道我在构造函数中启动了成员变量 m_strProjectData、m_pMetaData。但是最后一部分“QObject(aParent)”做了什么?它会创建一个基类对象并将其视为成员变量吗?

【问题讨论】:

【参考方案1】:

QObject(aParent) 使用aParent 参数调用QObject 的构造函数。 QObject 在这种情况下不是成员变量。这似乎是一个微妙的点,但它很重要,因为访问子对象的属性和方法的方式需要与访问成员变量不同的语法。

这是一个类比,试图理解子对象和成员变量之间的区别。

在电影《蝙蝠侠:黑夜》中有一个场景,蝙蝠侠在车里追着坏人。但是汽车损坏了,无法使用,他不得不逃跑。此时蝙蝠侠按下一个按钮,汽车的一部分与其他部分分离,变成了一辆摩托车。这有点像一个子对象。汽车is a摩托车。

现在考虑一辆 RV 牵引一辆较小的车辆的情况,这种情况在美国的高速公路上很常见。在这种情况下,RV has a 车辆。车辆是 RV 的成员变量。

【讨论】:

这不是我所理解的。 batman's car 既是 instance-of 摩托车又是汽车(不是 is-a,它是一个实例!)。虽然狮子是动物(两个类别)。 @Frank:诚然,这不是一个完美的类比。但我认为它的想法很好,这是我能想到的最好的类比!【参考方案2】:

本质上,这就是幕后发生的事情。对象的基类部分(如其数据成员)称为子对象

QObject(aParent) 中初始化基的概念类似于初始化成员,但基总是首先初始化。因此,在成员之前列出QObject 会更清楚,所以初始化列表是按时间顺序排列的。

无论初始化序列如何编写,初始化顺序始终遵循以class 命名的基类和声明成员的顺序。

【讨论】:

【参考方案3】:

作为派生类基类的类实例有时称为“基类子对象”,因此在某种意义上,基类是派生类的不同“部分”。

在构造函数的初始化列表中,QObject(aParent) 选择基类的构造方式。在这种情况下,将使用单个参数构造函数。如果派生类的构造函数的初始值设定项列表中省略了基类,则将使用其默认构造函数。

它不是严格意义上的成员变量,尽管它与成员变量一样是派生类的组成部分,与任何其他基类子对象和其他成员一样。

【讨论】:

【参考方案4】:

不完全是。它告诉基类的构造函数要做什么。想象一下这个类:

class A

public:
  A(int val)
    : value(val)
  
  
protected:
  int value;
;

要构造A,你必须传递一个int。这始终是正确的,即使您从中得出结论。

假设你是类B,它派生自A。你一个A,但你仍然需要告诉你类的A部分如何构建自己:

class B : public A

public:
  B()
    : A(5)
  
  

  int GetValue()
  
    return value;
  
;

A 的成员成为你的成员,因为你A

在机器内存中,场景有点像您描述的那样,但仅限于简单的情况。虚函数、多重继承和虚继承变得更加复杂。如果你坚持is-ahas-a 关系,那么你可能会避免一些头痛:)

【讨论】:

以上是关于当我在 C++ 中派生一个类时,它是不是会创建一个基类对象并将其作为我的成员变量存储在派生类中?的主要内容,如果未能解决你的问题,请参考以下文章

C ++中派生类的相等性测试[重复]

创建新的 C++ 类时如何使 XCode 使用 .hpp 标头而不是 .h?

C ++继承:具有基类类型的虚函数中派生类类型的参数

没有继承的链表[重复]

C++中派生类的构造函数怎么显式调用基类构造函数?

Qt中派生QAbatractProxyModel