C ++类前向声明​​的缺点是什么?

时间:2009-08-10 00:59:50

标签: c++ class typedef forward-declaration

我想在我的软件中使用类的前向声明,所以我可以使用typedef
并在类完整声明中使用它们。

像这样的Smth:

class myclass;
typedef boost::shared_ptr<myclass> pmyclass;
typedef std::list<pmyclass > myclasslist;

class myclass : public baseclass
{
private:        // private member declarations
        __fastcall myclass();

public:         // public member declarations
        __fastcall myclass(myclass *Parent)
            : mEntry(new myclass2())
          {
            this->mParent = Parent;
          }
        const myclass *mParent;
        myclasslist mChildren;
        boost::scoped_ptr<myclass2> mEntry;
};

所以我的问题是: 这种方法有什么缺点吗?我记得有关前向声明的析构函数问题的一些讨论,但我没有把所有内容都解决掉 还是有其他选择来实现这样的东西吗?

感谢。

编辑: 我找到了我所指的讨论:here

2 个答案:

答案 0 :(得分:22)

主要缺点是一切。前向声明是节省编译时间的折衷方案,让您在对象之间具有循环依赖关系。但是,成本是您只能使用类型作为引用,并且不能对这些引用执行任何操作。这意味着,没有继承,没有将它作为值传递,没有在该类中使用任何嵌套类型或typedef等等......这些都是很大的缺点。

您正在讨论的具体销毁问题是,如果您只转发声明类型并且碰巧只在模块中删除它,则行为未定义且不会抛出任何错误。

例如:

class A;

struct C 
{
    F(A* a)
    {
        delete a;  // OUCH!
    }
}

Microsoft C ++ 2008不会调用任何析构函数并抛出以下警告:

warning C4150: deletion of pointer to incomplete type 'A'; no destructor called
             : see declaration of 'A'

因此,您必须保持警惕,如果您将警告视为错误,这不应该是一个问题。

答案 1 :(得分:5)

来自C ++标准:

5.3.5 / 5:

“如果被删除的对象的类型不完整 删除和完整的类有一个非平凡的析构函数或 解除分配函数,行为未定义。“