未调用 C++ 析构函数,具体取决于链接顺序

标签 c++ gcc destructor

我在检查内存泄漏后在我的应用程序中遇到了这个问题,并发现我的一些类根本没有被销毁。

下面的代码分为 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 习惯用法的目标是不必在头文件中公开实现类的定义。但是所有标准智能指针都要求其模板参数的定义在声明点可见,以便正常工作。

这意味着这是您实际想要使用newdelete 和裸指针的极少数情况之一。 (如果我对此有误并且有一个可用于 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/

相关文章:

c++ - 对 pair 和 double 的映射进行排序

c++ - 具有枚举返回类型的函数无法在 C++ 类中解析

c++ - 模板实例化解析错误

c++ - 析构函数和 noexcept

c++ - 为什么 C++ 构造函数必须对数组使用动态分配?

C++ Libcurl : curl_easy_perform returned error code 28 when transferring files from linux system to windows remote system

c++ - tdm gcc 5.1 比 4.7 慢

gcc - 是否可以在目标文件上生成展开表

c++ - 关于我不理解的类对象的编译器行为

c++ - 链表的析构函数