c++;ctor和dtor don';我不能以同样的方式工作 我试图找出C++中类继承的技巧,并且我已经建立了一个示例项目: #include "stdafx.h" #include <iostream> using namespace std; class A { public: A() { cout << "Class A initialized" << endl; } ~A() { cout << "Class A destructed" << endl; } }; class B : public A { public: B() { cout << "Class B initialized" << endl; } ~B() { cout << "Class B destructed" << endl; } }; int _tmain(int argc, _TCHAR* argv[]) { cout << "A* a = new A()" << endl; A* a = new A(); cout << "B* b = new B ()" << endl; B* b = new B (); cout << "A* ab = new B()" << endl; A* ab = new B(); cout << "delete a" << endl; delete a; cout << "delete b" << endl; delete b; cout << "delete ab" << endl; delete ab; int i; cin >> i; return 0; }

c++;ctor和dtor don';我不能以同样的方式工作 我试图找出C++中类继承的技巧,并且我已经建立了一个示例项目: #include "stdafx.h" #include <iostream> using namespace std; class A { public: A() { cout << "Class A initialized" << endl; } ~A() { cout << "Class A destructed" << endl; } }; class B : public A { public: B() { cout << "Class B initialized" << endl; } ~B() { cout << "Class B destructed" << endl; } }; int _tmain(int argc, _TCHAR* argv[]) { cout << "A* a = new A()" << endl; A* a = new A(); cout << "B* b = new B ()" << endl; B* b = new B (); cout << "A* ab = new B()" << endl; A* ab = new B(); cout << "delete a" << endl; delete a; cout << "delete b" << endl; delete b; cout << "delete ab" << endl; delete ab; int i; cin >> i; return 0; },c++,inheritance,C++,Inheritance,我可以理解类B作为派生类的行为——首先它构造基类,然后构造派生类。当它调用析构函数时,它会以相反的方式进行工作。似乎合乎逻辑 我不明白的是ab的行为(我把B分配到A指针中), 为什么构造函数的行为与纯B相同,而析构函数只在A上运行 谢谢。编译器调用与指针的静态类型相对应的类的成员函数。指针ab的类型是A*,因此编译器调用类A的析构函数。例如,如果您将析构函数声明为虚拟的,则 class A { public: //... virtual ~A() { co

我可以理解类B作为派生类的行为——首先它构造基类,然后构造派生类。当它调用析构函数时,它会以相反的方式进行工作。似乎合乎逻辑

我不明白的是ab的行为(我把B分配到A指针中), 为什么构造函数的行为与纯B相同,而析构函数只在A上运行


谢谢。

编译器调用与指针的静态类型相对应的类的成员函数。指针ab的类型是
A*
,因此编译器调用类A的析构函数。例如,如果您将析构函数声明为虚拟的,则

class A
{
public:
    //...
    virtual ~A()
    {
        cout << "Class A destructed" << endl;
    }
};
A类
{
公众:
//...
虚拟~A()
{

构造函数和析构函数之间有根本的区别 (或构造函数和任何其他函数):何时 构造对象时,必须在源中指定其确切类型 对于所有其他函数(包括析构函数),它是 只要满足某些条件,就可以只提到一个基础。 其中一个条件是函数(或析构函数)是 基类中的虚拟

对于析构函数,还有一个附加约束,因为 析构函数涉及
删除
,这反过来需要 完整对象的地址,以便正确释放内存。 因此,给定
A*pA;
,类似
pA->f()
的表达式将调用 函数
f
在基类中,如果它不是虚拟的,而是函数
f()
在派生类中(如果它是虚拟的),并且派生类 重写它。另一方面,
delete pA;
将调用析构函数 如果基中的析构函数是虚的,但 未定义的行为,如果
pA
指向派生类,则 基地中的析构函数不是虚拟的,不存在公正的问题 9正在调用基类的析构函数;尽管这可能是 实际行为在简单情况下,行为在所有情况下都是未定义的

出于这个原因,经常建议如果一个类是 设计为用作基类,析构函数应该是 虚拟的,或受保护的。依类别而定:如果有 错误理解
std::exception
到编写以下内容的程度:

std::exception<...>* pIter = new std::vector<...>::iterator;
//  ...
delete pIter;
std::exception*pIter=newstd::vector::iterator;
//  ...
删除pIter;
没有希望,也不值得费心定义析构函数 对于
std::iterator
,只是为了保护它(在C++11之前的版本中,是
派生迭代器不可能是POD)。

因为您没有将
的析构函数
设置为虚拟的
析构函数。您是对的。我的错。谢谢。这个答案实际上是错误的;析构函数遵循的规则略有不同,事实上,他的程序有未定义的行为。重新阅读时:这个答案实际上是错误的(就像任何没有指出未定义行为的答案一样)。不。这是未定义行为。这就是为什么我说你的答案是错误的。见§5.3.5/3:“[…]如果要删除的对象的静态类型与其动态类型不同,则静态类型应为要删除的对象的动态类型的基类,并且静态类型应具有虚拟析构函数或行为未定义。”在这种情况下,程序崩溃,或者内存被破坏,导致以后崩溃,这并不罕见。哪个标准?我直接引用了C++11,where is说这是未定义的行为。我引用的文本在该标准的早期版本中是相同的。我引用的文本清晰而准确;我看不出你不理解的地方James Kanze《标准》毫无疑问地说,在这种情况下,基类的析构函数将被调用。这是这样一个调用的结果,具有未定义的行为。这是不同的事情。线程的作者问,为什么将被称为基类析构函数而不是派生类析构函数。所以这都是错误的除了你,因为你甚至不懂你读的东西。
std::exception<...>* pIter = new std::vector<...>::iterator;
//  ...
delete pIter;