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{};
};
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
.
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).
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