C++ 调用基类构造函数时隐式“this”

C++ 调用基类构造函数时隐式“this”,c++,this,C++,This,我希望下面的片段能够解释这一切: struct TBase { virtual void f() {} }; struct TDerived : public TBase { TDerived() { /* These are all fine either under GCC 4.4.3, ICC 12 and Comeau online: */ f(); this->f(); TBase::f(); this-&

我希望下面的片段能够解释这一切:

struct TBase {
  virtual void f() {}
};

struct TDerived : public TBase {
    TDerived() {
      /* These are all fine either under GCC 4.4.3, ICC 12 and Comeau online: */
      f();
      this->f();
      TBase::f();
      this->TBase::f();

      /* This one fails under Comeau: */
      TBase::TBase();

      /* While this one fails in every case: */
      //this->TBase::TBase();

      /* e.g. GCC says:
         test.cpp: In constructor ‘TDerived::TDerived()’:
         test.cpp:17: error: invalid use of ‘struct TBase’  */
    }
    void f() {}
};

问题是:为什么?也就是为什么TBASE::TBASE错误,根据C++?为什么->TBase::TBase更错误?

因为您不能直接调用任何构造函数§12.1 2 ISO/IEC 14882:2003E。如果要调用基类构造函数,必须在初始值设定项列表中执行,即:

TDerived() : TBase() {
}

这样做的主要原因是,当控件到达派生构造函数的第一个可执行代码行时,可以保证基类对象已完全构造§12.6.2 5和6 ISO/IEC 14882:2003E。由于构造函数通常用于资源获取,即RAII,如果允许它双重构造对象,则将是一个错误。

,因为您不能直接调用任何构造函数§12.1 2 ISO/IEC 14882:2003E。如果要调用基类构造函数,必须在初始值设定项列表中执行,即:

TDerived() : TBase() {
}

这样做的主要原因是,当控件到达派生构造函数的第一个可执行代码行时,可以保证基类对象已完全构造§12.6.2 5和6 ISO/IEC 14882:2003E。由于构造函数通常用于资源获取,即RAII,如果允许它双重构造对象,则将是一个错误。

TBase不是*this的成员,这就是为什么this->TBase::TBase;失败。@daknøk相同的参数适用于此->TBase::f?错。TBase不是*this的成员,这就是为什么this->TBase::TBase;失败。@daknøk相同的参数适用于此->TBase::f?错误。更一般地说,您不能直接调用任何构造函数,除非是在初始化器列表中。是的。添加了那个和对标准的引用。好的,对。但是由于构造函数没有名称,指定其作用域的目的是什么?我的意思是:为什么允许写TBase::TBase?首先,当你没有不同的构造函数作用域规则时,它应该更容易实现,这就是为什么我认为TBase::TBase首先是允许的。然而,发生的不是调用基类构造函数,而是此行创建了一个新的、类型为TBase的匿名对象,该对象立即被丢弃。@user1225822:类的名称被注入到类的作用域中,因此TBase::TBase相当于TBase,或者实际上相当于TBase::TBase::TBase::TBase::TBase。它指的是类,而不是构造函数。TBase::TBase会像int一样创建一个临时对象。一般来说,除了在初始化器列表中,您不能直接调用任何构造函数。是的。添加了那个和对标准的引用。好的,对。但是由于构造函数没有名称,指定其作用域的目的是什么?我的意思是:为什么允许写TBase::TBase?首先,当你没有不同的构造函数作用域规则时,它应该更容易实现,这就是为什么我认为TBase::TBase首先是允许的。然而,发生的不是调用基类构造函数,而是此行创建了一个新的、类型为TBase的匿名对象,该对象立即被丢弃。@user1225822:类的名称被注入到类的作用域中,因此TBase::TBase相当于TBase,或者实际上相当于TBase::TBase::TBase::TBase::TBase。它指的是类,而不是构造函数。TBase::TBase创建一个临时对象,就像int也会创建一样。