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; }
我可以理解类B作为派生类的行为——首先它构造基类,然后构造派生类。当它调用析构函数时,它会以相反的方式进行工作。似乎合乎逻辑 我不明白的是ab的行为(我把B分配到A指针中), 为什么构造函数的行为与纯B相同,而析构函数只在A上运行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
谢谢。编译器调用与指针的静态类型相对应的类的成员函数。指针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;