推导过程中形成的未命名对象

Posted

技术标签:

【中文标题】推导过程中形成的未命名对象【英文标题】:Unnamed objects formed during derivation 【发布时间】:2011-08-17 03:11:54 【问题描述】:

抽象类,即具有至少一个纯虚函数的类不允许对象实例化。但是当我们从这个抽象类派生出一个具体的类并定义了所有的纯虚函数时,我们就可以实例化这个类的一个对象。

但是当创建派生对象时,首先必须创建一个未命名的基类对象。这是怎么发生的?我的意思是如果不允许创建这个未命名的抽象基类对象,如何创建它。

【问题讨论】:

这可能是特定于编译器的。 您必须首先创建基类对象的基本假设是有缺陷的。一个对象是一个完整的对象,派生类型的基类部分是一个子对象(并且不是一个对象它自己的权利)。标准中明确说明了这一点,请参阅第 1.8 节 [intro.object]。第 3 段定义了一个complete object of x,其中 x 是对象的一部分。还有第 3.8 节对象生命周期 [basic.life] 明确指出:类型 T 的 object 的生命周期开始于:1) 已获得存储 2) 初始化完成。 【参考方案1】:

这就像说人的心不能存在,因为它需要人。但是当我们创造一个人时,我们必须首先创造心脏,但是如果没有人,心脏就无法存在,我们如何创造它。

答案是因为我们一起创建它们,它们都是单个实体的一部分。 心与人是共同创造的。 在构造函数完全完成之前,没有对象实际上存在,此时 heart 和 human 作为单个对象存在。

【讨论】:

【参考方案2】:

您将“不可能”与“不允许”混淆了。当然,编译器可以实例化抽象类;它只是不允许程序员

【讨论】:

我认为 Eugene 是对的,编译器可以创建这个未命名的抽象基,但程序员不行。必须创建未命名的基类对象。例如,考虑一个基类,它在程序中存在多个同类对象时抛出异常。这种簿记可以简单地通过使用静态 int 数据成员来完成。让我们称之为 SingleInstance_Base 类。现在假设一个类派生自这个名为 DerivedFromSingleInstance_Base 的基类。现在,如果我们创建两个对象,例如: SingleInstance_Base objBase; DerivedFromSingleInstance_Base objDerived; 我们将在第二条语句中得到一个运行时错误,因为首先创建了一个未命名的 SingleInstance_Base 对象,然后开始创建 DerivedFromSingleInstance_Base。【参考方案3】:

当派生对象被创建时,首先一个未命名的基类对象有 被创建。这是怎么发生的?

IMO,基类对象没有以我们看到的方式创建。是的,我们确实在基类中提供了构造函数和方法等,但它们仅仅是初始化/分配的工具。

实际上,派生类继承了它的基础部分,所以最终我们只是创建派生类对象。类比例子:

struct B 
  int b;
  virtual void foo() = 0;
;

struct D : B 
  int d;
  virtual void foo () 
;

在创建对象时,编译器会将D 视为,

struct D 
  int b,d;
  virtual void foo () 
;

它看到D 满足了能够实例化一个对象的所有条件并创建了该对象。

【讨论】:

以上是关于推导过程中形成的未命名对象的主要内容,如果未能解决你的问题,请参考以下文章

UML基础

访问 Ajax 对象中的未命名值

算法学习笔记--余数定理

列表推导式 生成器表达式

Python推导式

机器学习算法推导过程中的数据基础知识