Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/144.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 智能指针:a';基数';是否创建了对象的一部分?_C++_C++11_C++14 - Fatal编程技术网

C++ 智能指针:a';基数';是否创建了对象的一部分?

C++ 智能指针:a';基数';是否创建了对象的一部分?,c++,c++11,c++14,C++,C++11,C++14,我不明白为什么会这样。当对象无法完全构造时,派生对象的一部分是否会杀死对象的基础部分 有人能解释一下原因吗?构造函数在进入自己的主体之前先处理其成员初始化列表。因此,在本例中,Derived()在进入自己的主体之前,按该顺序调用Base()和Member() Derived()首先调用Base()(隐式地,因为您没有在Derived()的成员初始化列表中显式指定Base())。输入了Base()的主体,因此您可以在输出中看到Base:::ctor。不会引发异常,因此Base()会正常退出 Der

我不明白为什么会这样。当对象无法完全构造时,派生对象的一部分是否会杀死对象的基础部分


有人能解释一下原因吗?

构造函数在进入自己的主体之前先处理其成员初始化列表。因此,在本例中,
Derived()
在进入自己的主体之前,按该顺序调用
Base()
Member()

Derived()
首先调用
Base()
(隐式地,因为您没有在
Derived()
的成员初始化列表中显式指定
Base()
)。输入了
Base()
的主体,因此您可以在输出中看到
Base:::ctor
。不会引发异常,因此
Base()
会正常退出

Derived()
继续调用
Member()
下一步。已输入
Member()
的主体,因此您可以在输出中看到
Member::ctor
。但是
Member()
在退出之前抛出一个异常,所以
Member
对象的构造被中止

异常进入并转义
派生()
,因此
派生()
也被中止。由于
Derived()
已从其成员初始化列表中中止,因此未输入其正文,因此在输出中看不到
Derived::ctor

由于未完全构造
成员
对象,因此未调用
~Member()
,因此在输出中看不到
Member::dtor

由于
派生的
Base
部分在引发异常之前已完全构造,因此会自动调用
~Base()
,因此您可以在输出中看到
Base::dtor

由于
Derived
对象未完全构造,因此未调用
~Derived()
,因此在输出中看不到
Derived::dtor

简而言之,每当一个异常从构造函数中逃逸时,只有成功构造的类的片段(基类和数据成员一样)会被单独自动销毁。未完全构造的碎片不会自动销毁。这种行为是由C++标准保证的。
当异常向上传播到调用堆栈时,它会中止它所转义的所有构造函数,直到捕获到异常,或者异常转义
main()
,导致进程终止。

同样,如果您的
Member1
Member2
Member3
顺序相同,而
Member2
抛出了一个异常,将调用
Member1
Base
析构函数,但不会调用其他析构函数中的任何一个。@DanielH:在我的回答中,“只有已成功构造的类的片段”涵盖了这一点是的,但这也可能意味着“作为一个组的所有基”或其他什么。我要澄清的是,每个成员和每个基地都是单独考虑的。
#include <iostream>
#include <memory>
class Member {
public:
  Member() {
    std::cout << "Member::ctor" << std::endl;
    throw "Exception";
  }
  ~Member() {
    std::cout << "Member::dtor" << std::endl;
  }
};
class Base {
public:
  Base() {
    std::cout << "Base::ctor" << std::endl;
  }
  virtual ~Base() {
    std::cout << "Base::dtor" << std::endl;
  }
};

class Derived : public Base {
  Member* m_;
  public:
    Derived() : m_(new Member()) {
      std::cout << "Derived::ctor" << std::endl;
    }
  ~Derived() {
    if(m_) delete m_;
      std::cout << "Derived::dtor" << std::endl;
    }
};

int main(int argc, char** argv) {
try{
  std::unique_ptr<Base> b = std::make_unique<Derived>();
  std::cout << "No Exception" << std::endl;
  }
  catch(...)
  {
    std::cout << "Exception" << std::endl;
  }
}
Base::ctor
Member::ctor
Base::dtor
Exception