智能指针是否打破了头文件中最小化#include的原则?

Do smart pointers break the principle of minimizing #includes in header files?

本文关键字:最小化 #include 原则 文件 是否 指针 智能      更新时间:2023-10-16

我更喜欢在头文件中尽量减少#include的使用,尽可能使用前向声明,我相信这是一种很好的做法。

如果我有一个像 这样的方法声明,它会很好地工作:
bool IsFlagSet(MyObject *pObj);

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

bool IsFlagSet(MyObjectPtr pObj);

我现在不 #include "MyObject.h"吗?是否有其他方法可以解决这个问题,或者这只是使用智能指针的代价?

不,你不需要。你可以为一个不完整的类定义一个类型别名,模板参数可以是不完整的类型(参见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);
}

不,std::shared_ptr<T>被明确设计为只在T前向声明时工作。当然,这并不适用于所有情况,但原理与普通指针相同。如果T是前向声明的,你可以用std::shared_ptr<T>T*能做的任何事情。

可以对不完整类型使用typedef。

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

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