#include <iostream>
class B {
public:
B() {}
void p() const { std::cout << "B::p\n"; }
void q() const { std::cout << "B::q\n"; }
int b;
};
class D : public B {
public:
D() {}
virtual void p() const { std::cout << "D::p\n"; }
virtual void q() const { std::cout << "D::q\n"; }
int d;
};
int main(int argc, char const *argv[])
{
B b;
D d;
B* pb = new B;
B* pd = new D;
D* pd2 = new D;
b.p(); b.q();
d.p(); d.q();
pb->p(); pb->q();
pd->p(); pd->q();
pd2->p(); pd2->q();
delete pb;
delete pd;
delete pd2;
return 0;
}
好像delete pd
中存在内存泄漏。我想pd
不是指向D
的指针,所以当我delete
它时,它不会调用D
的析构函数,而是B
的析构函数{1}}。但是,我不知道具体原因。谁能帮帮我?感谢。
答案 0 :(得分:3)
您的代码中可能存在内存泄漏。但同样地,可能没有。
如评论中所述,此序列
B* pd = new D;
delete pd;
代码中的(与您提供的所有其他代码无关)给出了未定义的行为,因为B
没有virtual
析构函数。
当行为未定义时,任何事情都可能发生,包括内存泄漏或您可能或可能无法想象的任何其他内容。
如果为virtual
声明B
析构函数,并定义它以使其不会泄漏内存(例如virtual ~B() {}
),那么您的代码将具有明确定义的行为。使用运算符new
正确销毁了使用运算符delete
创建的所有对象,因此 - 如果B
具有虚拟析构函数 - 它们都不会导致内存泄漏。
答案 1 :(得分:0)
你怎么知道D的析构函数没有被调用?您的示例代码甚至没有析构函数。实际上,它不会像评论中所指出的那样调用D的析构函数。在基类中没有虚拟析构函数并不好。
尝试以下示例,
#include <iostream>
class B {
public:
B() {}
virtual ~B() { std::cout << "B::dtor\n"; }
void p() const { std::cout << "B::p\n"; }
void q() const { std::cout << "B::q\n"; }
int b;
};
class D : public B {
public:
D() {}
virtual ~D() { std::cout << "D::dtor\n"; }
virtual void p() const { std::cout << "D::p\n"; }
virtual void q() const { std::cout << "D::q\n"; }
int d;
};
int main(int argc, char const *argv[])
{
B b;
D d;
B* pb = new B;
B* pd = new D;
D* pd2 = new D;
b.p(); b.q();
d.p(); d.q();
pb->p(); pb->q();
pd->p(); pd->q();
pd2->p(); pd2->q();
delete pb;
delete pd;
delete pd2;
return 0;
}
对于你的问题,你的实现有一个漏洞,因为pd被删除了可能不会调用用D的dtor编写的内存清理。
答案 2 :(得分:-1)
B* pb = new B;
//B::B()
B* pd = new D;
//B::B() <-- constructor called
//D::D() <-- constructor called
D* pd2 = new D;
//B::B()
//D::D()
....
pd->p(); pd->q();
//B::p
//B::q
....
delete pb;
//~B::B()
delete pd;
//~B::B() <-- leaks here
delete pd2;
//~D::D()
//~B::B()
你应该使用关键字&#34; virtual&#34;对于B类的析构函数:
private:
virtual ~B() {}