【问题标题】:C++ Class forward declaration drawbacks?C++ 类前向声明​​的缺点?
【发布时间】:2010-11-18 04:09:47
【问题描述】:

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

像这样的:

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

【问题讨论】:

    标签: c++ class typedef forward-declaration


    【解决方案1】:

    主要缺点是一切。前向声明是节省编译时间并让您在对象之间具有循环依赖关系的折衷方案。但是,代价是您只能将类型用作引用,而不能对这些引用做任何事情。这意味着,没有继承,没有将其作为值传递,没有在该类中使用任何嵌套类型或 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'
    

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

    【讨论】:

    • 如果所有这些痛苦在一个月内为您节省了 30 分钟的编译时间,但因前向声明的头痛而花费了您一个小时的时间 - 那么您就输了...购买具有更多内核的 CPU 和而是启用并行编译。至少你可以在之后以更好的帧速率在上面播放 Skyrim。
    【解决方案2】:

    来自 C++ 标准:

    5.3.5/5:

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

    【讨论】:

    • 好吧,对不起,我之前读过它,我的问题是:如果它是在声明后立即定义的,应该没有问题,对吧?
    • 是的,我就是这么读的。希望我们的编译器符合标准:-)
    猜你喜欢
    • 2021-12-25
    • 1970-01-01
    • 2023-03-16
    • 2011-07-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多