Reputation: 14869
I am developing a library and a would like to provide my users a public interface separate from the real implementation that is hidden in a namespace. This way, I could change only the class HiddenQueue without changing myQueue that will be exposed to users only.
If I put the C++ code of HiddenQueue in the myQueue.cpp file the compiler complains saying _innerQueue has incomplete type. I thought that the linker was able to resolve this. What I am doing wrong here?
// myQueue.h
namespace inner{
class HiddenQueue;
};
class myQueue{
public:
myQueue();
);
private:
inner::HiddenQueue _innerQueue;
};
///////////////////////////
// myQueue.cpp
namespace inner{
class HiddenQueue{};
};
Upvotes: 4
Views: 1766
Reputation: 31233
You need to provide pointer to _innetQueue rather then the object itself:
std::auto_ptr<inner::HiddenQueue> _innerQueue;
Search form pimpl ideom or d-pointer
Upvotes: 1
Reputation: 437376
The compiler needs to know the exact memory layout of an object by looking at the header file it's defined in.
Your code says that class MyQueue
has a member of type InnerQueue
, which will be part of the memory layout of MyQueue
objects. Therefore, to deduce the memory layout of MyQueue
it needs to know the memory layout of InnerQueue
. Which it does not, because you say "oh well, it's defined elsewhere".
What you are trying to do is closely related to "the PIMPL idiom"/"compiler firewall" technique.
To solve the problem, you must either include HiddenQueue.h in your header or declare _innerqueue as a pointer:
class myQueue {
public:
myQueue();
private:
inner::HiddenQueue* _pinnerQueue;
};
Using a pointer is possible because a pointer has a known memory size (dependent on your target architecture), therefore the compiler doesn't need to see the full declaration of HiddenQueue
.
Upvotes: 6
Reputation: 52284
To be able to make a member of a class, you need to have a definition for it and not only a declaration. (A declaration is enough for a pointer or a reference to the class).
Upvotes: 1