12

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

像这样:

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;
};

所以我的问题是:这种方法有什么缺点吗?我记得一些关于前向声明的析构函数问题的讨论,但我并没有把所有东西都拿出来。
或者有没有其他选择来实现这样的事情?

谢谢。

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

4

2 回答 2

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'

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

于 2009-08-10T01:49:45.203 回答
5

从 C++ 标准:

5.3.5/5:

“如果被删除的对象在删除点具有不完整的类类型,并且完整的类具有非平凡的析构函数或释放函数,则行为未定义。”

于 2009-08-10T01:10:31.770 回答