我在检查内存泄漏后在我的应用程序中遇到了这个问题,并发现我的一些类根本没有被销毁。
下面的代码分为 3 个文件,它应该实现一个名为 pimpl 的模式。 .预期的场景是让 Cimpl
构造函数和析构函数打印它们的消息。然而,这不是我用 g++ 得到的。在我的应用程序中,只调用了构造函数。
类.h:
#include <memory>
class Cimpl;
class Cpimpl {
std::auto_ptr<Cimpl> impl;
public:
Cpimpl();
};
类.cpp:
#include "classes.h"
#include <stdio.h>
class Cimpl {
public:
Cimpl() {
printf("Cimpl::Cimpl()\n");
}
~Cimpl() {
printf("Cimpl::~Cimpl()\n");
}
};
Cpimpl::Cpimpl() {
this->impl.reset(new Cimpl);
}
主要.cpp:
#include "classes.h"
int main() {
Cpimpl c;
return 0;
}
以下是我能够进一步发现的内容:
g++ -Wall -c main.cpp
g++ -Wall -c classes.cpp
g++ -Wall main.o classes.o -o app_bug
g++ -Wall classes.o main.o -o app_ok
看起来析构函数在两种可能情况之一中被调用,这取决于链接顺序。使用 app_ok 我能够获得正确的场景,而 app_bug 的行为与我的应用程序完全一样。
在这种情况下我是否缺少任何智慧? 感谢您提前提出任何建议!
最佳答案
pimpl 习惯用法的目标是不必在头文件中公开实现类的定义。但是所有标准智能指针都要求其模板参数的定义在声明点可见,以便正常工作。
这意味着这是您实际想要使用new
、delete
和裸指针的极少数情况之一。 (如果我对此有误并且有一个可用于 pimpl 的标准智能指针,请有人告诉我。)
类.h
struct Cimpl;
struct Cpimpl
{
Cpimpl();
~Cpimpl();
// other public methods here
private:
Cimpl *ptr;
// Cpimpl must be uncopyable or else make these copy the Cimpl
Cpimpl(const Cpimpl&);
Cpimpl& operator=(const Cpimpl&);
};
类.cpp
#include <stdio.h>
struct Cimpl
{
Cimpl()
{
puts("Cimpl::Cimpl()");
}
~Cimpl()
{
puts("Cimpl::~Cimpl()");
}
// etc
};
Cpimpl::Cpimpl() : ptr(new Cimpl) {}
Cpimpl::~Cpimpl() { delete ptr; }
// etc
关于未调用 C++ 析构函数,具体取决于链接顺序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12323028/