Temple
Temple

Reputation: 1631

invalid use of incomplete type error

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

Answers (2)

zdf
zdf

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

Kerrek SB
Kerrek SB

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

Related Questions