永远不要在 PIMPL 中提供析构函数(使用 boost scoped_ptr),g++(4.6.1) 不会生成编译错误,为什么?

Never provide destructor in the PIMPL(using boost scoped_ptr), the g++(4.6.1) doesn't generate compile error, Why?

本文关键字:g++ 为什么 错误 编译 PIMPL 析构函数 永远 scoped boost 使用 ptr      更新时间:2023-10-16

在我阅读了参考链接:必须在PIMPL中提供析构函数之后,我遵循了示例,但是g++(4.6.1)没有像我预期的那样生成编译错误

源代码为:

// Predeclare.h
#include <vector>
#include <boost/scoped_ptr.hpp>
#include <iostream>
struct A;
class Predeclare
{
    std::vector<A> alist_;
    boost::scoped_ptr<A> pa_;
    //A a;
public:
    Predeclare();
    //~Predeclare();
    void print();
    void set(int i);
};

// Predeclare.cpp
#include "Predeclare.h"
struct A
{
    int a;
};
Predeclare::Predeclare(): pa_(new A)
{}
/*
Predeclare::~Predeclare()
{}
*/
void Predeclare::print()
{
    std::cout << pa_->a << 'n';
}
void Predeclare::set(int i)
{
    pa_->a = i;
}
int main()
{
    Predeclare c1;
    c1.set(10);
    c1.print();
    return 0;
}

然后编译程序

g++ Predeclare.cpp

一切正常,为什么g++(4.6.1)不生成编译错误?

在您的示例中,编译器只需要在main()中声明c1时才需要Predeclare的析构函数。到那时,A已经在前面的Predeclare.cpp中定义过了。

如果您尝试在不同的源文件中实例化Predeclare,您可能会遇到问题。

注意,在A不完整的情况下实例化std::vector<A>会产生未定义的行为。当你实例化一个容器时,值类型必须是Destructible,并且只有完整类型才是Destructible。