代码之家  ›  专栏  ›  技术社区  ›  shoosh

C++:自动_ptr+转发声明?

  •  12
  • shoosh  · 技术社区  · 14 年前

    我有一门课是这样的:

    class Inner;
    
    class Cont
    {
    public:
        Cont();
        virtual ~Cont();
    private:
        Inner* m_inner;
    };
    

    在.cpp中,构造函数创建 Inner 具有 new delete 就这样。这很有效。
    现在我想更改此代码以使用 auto_ptr 所以我写:

    class Inner;
    
    class Cont
    {
    public:
        Cont();
        virtual ~Cont();
    private:
        std::auto_ptr<Inner> m_inner;
    };
    

    现在,构造函数初始化了 自动检查 析构函数什么也不做。

    但它不起作用。当我实例化这个类时,问题似乎出现了。我得到这个警告:

    警告C4150:删除指向的指针 调用析构函数

    这显然是非常糟糕的,我理解为什么会发生这种情况,编译器不知道 在实例化 auto_ptr<Inner>

    所以我的问题是:有没有一种使用 自动检查
    不得不 #include

    7 回复  |  直到 10 年前
        1
  •  13
  •   sharptooth    14 年前

    您需要包含标题定义 class Inner Cont::~Cont() 实现位于。这样,在头定义中仍然有一个转发声明 class Cont 编译器会看到 班级内部 定义并可以调用析构函数。

    //Cont.h
    class Inner; // is defined in Inner.h
    class Cont 
    { 
        virtual ~Cont(); 
        std::auto_ptr<Inner> m_inner;
    };
    
    // Cont.cpp
    #include <Cont.h>
    #include <Inner.h>
    
    Cont::~Cont()
    {
    }
    
        2
  •  4
  •   shoosh    13 年前

    事实证明,只有当我将c'tor内联时,问题才会出现。如果我把c'tor放在cpp里,在 Inner 一切都好。

        3
  •  3
  •   Pavel Radzivilovsky    14 年前

    您可以考虑Booo::SydDypTr.()。与性能相比,它没有实际的缺点,并且对于转发声明更加友好:

    boost::shared_ptr<class NeverHeardNameBefore> ptr;

    没关系,上面没有额外的声明。

    shared_ptr比auto_ptr做得更多,比如引用计数,但如果您不需要它,它应该不会有什么害处。

        4
  •  3
  •   Antern    11 年前

    这似乎很可笑,但我通过添加 #include <memory> 到Cont.h文件。

        5
  •  2
  •   jjth    13 年前

    如其他人所指出的,如果在cont.cpp文件中实现析构函数并包含internal.h,则头中的转发声明是可以的。

    问题可能在于Cont的使用。在使用(和销毁)Cont的每个cpp中,您必须包括Cont.h和inner.h。这就解决了我的问题。

        6
  •  0
  •   Community Egal    7 年前

    This question (使用私有析构函数删除对象)和 this question

        7
  •  0
  •   Brian Neal    14 年前

    从技术上讲,您不应该用不完整的类型实例化标准库模板,尽管我知道没有哪种实现不起作用。实际上,Sharptooth的答案也是我推荐的。

    对impl指针使用裸指针并没有什么问题,只要在析构函数中对其调用delete。您可能还应该实现或禁用复制构造函数和赋值运算符。