c ++我应该使用前向声明吗?

时间:2011-10-27 21:29:19

标签: c++ include forward-declaration

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

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

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

更新

只是为了扩展shared_ptr问题(我现在不是在使用它们,而是考虑切换)。如果我要使用它们,我想我会在类中使用typedef的shared_ptr类型。 E.g:

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

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

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

似乎可能会让事情变得更加混乱。这会对前向声明产生问题,如果是这样,有一个简单的解决方法吗?

4 个答案:

答案 0 :(得分:5)

您可能希望这样做,因为包含文件会使编译时间更长,但根据您拥有的案例数量和代码库的大小,很可能不会出现问题。

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

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

答案 1 :(得分:1)

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

答案 2 :(得分:1)

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

答案 3 :(得分:-1)

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

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

BTW有一个标准头文件<iosfwd>,它包含某些流类型的前向声明。它似乎是专门发明的,所以你可以声明operator<<(std::ostream&, ...)(这是我的个人意见,抱歉,如果它毕竟是错的)。


修改:关于shared_ptr<type>

粗略地说,使用共享指针(对于前向声明的类型),唯一可以做的就是声明函数。如果您想定义一个对shared_ptr<type>执行有用功能的函数,则不能只转发声明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为你的班级提供完整的声明。