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.
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:
bool IsFlagSet(MyObjectPtr pObj);
Do I not now have to #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):
#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:
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. 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*
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With