【问题标题】:c++ Should I use forward declaration?c++ 我应该使用前向声明吗?
【发布时间】:2011-10-27 21:29:18
【问题描述】:

我发现这个问题When to use forward declaration? 很有用,但它是描述性的而不是规定性的。

我的场景通常是我使用指向另一个类的指针作为类成员或函数参数,所以我在标头中需要的只是前向声明(另外,如果我要切换到使用 boost shared_ptr's它们是否与使用前向声明兼容?)。目前我只包括标题,但现在我想知道是否应该使用前向声明。

所以我的问题是,如果我可以对类使用前向声明,应该吗?我希望这个问题不是主观的,但如果没有最佳实践答案,那么使用前向声明的优缺点是什么?

更新

只是为了扩展 shared_ptr 问题(我现在没有使用它们,但正在考虑切换)。如果我要使用它们,我想我会使用在类中对 shared_ptr 类型进行 typedef 的做法。例如:

class Customer
{
public:
    typedef std::tr1::shared_ptr<Customer> SharedPointer;

    Customer() {}   
    virtual ~Customer() {}

    virtual std::string GetName() const;
};

似乎这可能会使事情变得更加混乱。前向声明会有问题吗?如果有,有简单的解决方法吗?

【问题讨论】:

    标签: c++ include forward-declaration


    【解决方案1】:

    您可能希望这样做,因为包含文件会使编译时间更长,但取决于您有多少案例以及您的代码库有多大,这很可能不会成为问题。

    要考虑的另一件事是依赖关系。您不想因为包含文件更改而重新编译所有代码,而您只需要指针定义。

    所以我的(主观)答案是是的,你应该

    【讨论】:

    • 只是为了完成答案:是的,boost::shared_ptr 可以正常使用前向声明
    • 速度更快,避免问题。是的,绝对更喜欢预先声明而不是包含。
    【解决方案2】:

    是的,你应该这样做。请记住,当您的代码的客户使用它时,您包含在标头中的任何内容也会包含在内。最好只在标头中包含所需的最少文件数。除此之外,如果您不需要包含整个文件并且前向声明就足够了,那么这似乎是一个简单的选择。

    【讨论】:

      【解决方案3】:

      我认为最好使用前向声明来提高编译速度(不包括大量文件) 对于使用共享指针的问题,它不会改变任何东西,因为共享指针只是一个负责清理堆内存的包装器

      【讨论】:

        【解决方案4】:

        他们通常说您应该尽可能使用前向声明。与所有规则一样,此规则也有例外。对我来说,例外情况通常是类型名称过于复杂(即 template),或者名称太多时。例如,以下是前向声明:

        namespace foo
        {
            namespace bar
            {
                template <typename T1, typename T2, int X>
                class MyNiftyType;
                // Hmm, maybe declare more types here?
            }
            // Hmm, maybe declare even more types here?
        }
        

        如果只做#include "MyNiftyStuff.h"就可以避免这些事情,我最好#include

        顺便说一句,有一个标准头文件&lt;iosfwd&gt;,其中包含一些流类型的前向声明。它似乎是专门发明的,因此您可以声明operator&lt;&lt;(std::ostream&amp;, ...)(这是我个人的看法,如果有错误,请见谅)。


        编辑:关于shared_ptr&lt;type&gt;

        粗略地说,使用共享指针(指向前向声明的类型)唯一能做的就是声明函数。如果你想定义一个对shared_ptr&lt;type&gt; 有用的函数,你不能只前向声明type。例如:

        MyCode.h

        class MyClass;
        void DoMuchStuff(shared_ptr<MyClass> ptr); // declaration - OK
        inline void DoDoubleStuff(shared_ptr<MyClass> ptr) // definition - not OK!
        {
            void DoMuchStuff(ptr);
            void DoMuchStuff(ptr);
        }
        

        如果我使用普通指针而不是shared_ptr,这将适用于前向声明。但是这种不便很少会影响到您 - 要么您的 .h 文件中只有声明,要么您的内联函数非常复杂,以至于无论如何您都必须 #include 为您的类提供完整的声明。

        【讨论】:

        • 对,直到您#include 某些东西在包含在另一个文件中时会导致问题。如果权衡是更快的编译和更不容易出错的代码结构,谁在乎类型名称是否长?
        猜你喜欢
        • 1970-01-01
        • 2011-10-09
        • 1970-01-01
        • 1970-01-01
        • 2010-12-29
        • 2021-12-25
        • 1970-01-01
        相关资源
        最近更新 更多