简体   繁体   English

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

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

I prefer to minimize the use of #include in my header files, using forward declarations wherever possible, and I believe this is considered good practice. 我更喜欢在我的头文件中最小化#include的使用,尽可能使用前向声明,我相信这被认为是一种很好的做法。

It works great if I have a method declaration like: 如果我有一个方法声明,它的效果很好:

bool IsFlagSet(MyObject *pObj);

However if I have typedef Ptr<MyObject> MyObjectPtr in MyObject.h and the API changes to: 但是,如果我在MyObject.htypedef Ptr<MyObject> MyObjectPtr MyObject.h并且API更改为:

bool IsFlagSet(MyObjectPtr pObj);

Do I not now have to #include "MyObject.h" ? 我现在不必 #include "MyObject.h"吗? Is there any way around this, or is it just the price one pays for using smart pointers? 有没有办法解决这个问题,还是仅仅是使用智能指针付出的代价?

No, you do not have to. 不,你不必。 You can define a type alias for an incomplete class, and template arguments can be incomplete types (see Paragraph 14.3.1/2 of the C++11 Standard): 您可以为不完整的类定义类型别名,模板参数可以是不完整的类型(请参阅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();
}

As correctly mentioned by Pubby in the comments, function declarations do not require the types mentioned in their signature to be complete either: 正如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);
}

No, std::shared_ptr<T> is explicitly designed to work when T is only forward-declared. 不, std::shared_ptr<T>明确设计为在T仅向前声明时工作。 Of course, this does not work for all cases, but the principle is the same as for a plain pointer. 当然,这并不适用于所有情况,但原理与普通指针相同。 If T is forward-declared, you can do anything with std::shared_ptr<T> that you could do with T* . 如果T是向前声明的,你可以用std::shared_ptr<T>做任何你可以用T*做的事情。

you can use typedef with incomplete type. 你可以使用不完整类型的typedef。

But isn't it better to use full name of the smart pointer type? 但是使用智能指针类型的全名是不是更好?

MyClassPtr is of course much shorter, but std::unique_ptr<MyClass> actually tells us how to use this pointer. MyClassPtr当然要短得多,但是std::unique_ptr<MyClass>实际上告诉我们如何使用这个指针。 So for not very long names I suggest using full names of smart pointers. 因此,对于不长的名称,我建议使用智能指针的全名。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM