Reputation: 1631
This is simplified code just to show my question:
main.cpp
#include "one.hpp"
#include <iostream>
int main(){
One one;
std::cout << one.two->val;
}
one.hpp:
struct Two; <- forward declare Two
struct One{
One();
~One() { delete two;}
Two* two;
};
one.cpp
#include "one.hpp"
struct Two{
int val;
};
One::One(): two(new Two()) {}
When compiling this I get error invalid use of incomplete type 'struct Two'. I assume that since Two is incomplete type I just cannot refer to its fields... I am wondering is there any way to hide Two implementation in one cpp file and use it in another cpp file using this kind of forward declaration? Question comes from creating API where I would like to hide implementation on some classes.
Upvotes: 1
Views: 3938
Reputation: 4808
Wikipedia: "Opaque pointers are a way to hide the implementation details of an interface from ordinary clients, so that the implementation may be changed without the need to recompile the modules using it. ":
Header file released to clients:
struct opaque;
struct interface
{
~interface();
void test();
opaque* _p;
};
Header file not released to clients:
struct opaque
{
void test();
//...
};
interface
implementation file:
#include "interface.h"
#include "opaque.h"
interface::~interface()
{
delete _p;
}
void interface::test()
{
_p->test();
}
// ...
opaque
implementation file:
#include "opaque.h"
void opaque::test()
{
// actual implementation
}
Upvotes: 1
Reputation: 476990
You cannot delete an object of incomplete type.
The solution is to define the destructor in one.cpp, too.
one.hpp:
struct One {
~One();
// ...
};
one.cpp:
// ...
One::~One() { delete two; }
Upvotes: 3