智能指针是否违反了最小化头文件中#includes的原则?

时间:2013-03-22 14:59:53

标签: c++

我更喜欢尽可能地使用前向声明来最小化我的头文件中#include的使用,我相信这被认为是一种很好的做法。

如果我有一个方法声明,那么它很有用:

bool IsFlagSet(MyObject *pObj);

但是,如果typedef Ptr<MyObject> MyObjectPtr中有MyObject.h且API已更改为:

bool IsFlagSet(MyObjectPtr pObj);

我现在 #include "MyObject.h"了吗?有没有办法解决这个问题,还是仅仅是使用智能指针付出的代价?

3 个答案:

答案 0 :(得分:9)

不,你没必要。您可以为不完整的类定义类型别名,模板参数可以是不完整的类型(参见C ++ 11标准的第14.3.1 / 2段):

#include <memory>

struct C;

typedef std::shared_ptr<C> ptrC; // C is incomplete here

struct C { void foo() { } };

int main()
{
    ptrC p = std::make_shared<C>();
    p->foo();
}

正如评论中Pubby正确提到的那样,函数声明不要求其签名中提到的类型也是完整的:

struct C;

void foo(C); // C is incomplete here

struct C { };

#include <iostream>

void foo(C)
{
    std::cout << "foo(C)" << std::endl;
}

int main()
{
    C c;
    foo(c);
}

答案 1 :(得分:3)

不,std::shared_ptr<T>明确设计为仅在T向前声明时才有效。当然,这并不适用于所有情况,但原理与普通指针相同。如果T是向前声明的,您可以使用std::shared_ptr<T>T*执行任何操作。

答案 2 :(得分:0)

你可以使用不完整类型的typedef。

但使用智能指针类型的全名是不是更好?

MyClassPtr当然要短得多,但std::unique_ptr<MyClass>实际上告诉我们如何使用这个指针。因此,对于不长的名称,我建议使用智能指针的全名。