5

My problem is straightforward: I am using SDL to create a simple simulation and I want to store instances of TTF_Font type in smart pointers (shared_ptr), but I keep getting this error:

"invalid application of ‘sizeof’ to incomplete type '_TTF_Font'"

Is there any way to use smart pointers with incomplete types from external libraries without incorporating their source code into my program?

EDIT:

TTF_Font is declared as

typedef struct _TTF_Font TTF_Font;

_TTF_Font is in turn defined in compiled external library.

My usage of TTF_Font is simply just constructing a new stack allocated instance of shared_ptr with a raw pointer to TTF_Font:

auto font_sp = std::shared_ptr<TTF_Font>(font_p);

I don't use sizeof explicitly here.

Paweł Motyl
  • 1,304
  • 10
  • 16
  • 4
    Please show some code. How are you using the sizeof operator and what is the TTF_Font defined as? – Twifty Jul 15 '13 at 08:38

1 Answers1

7

Usually having a shared_ptr of an incomplete type should work. You can declare a function like this

typedef struct _TTF_Font TTF_Font;
std::shared_ptr<TTF_Font> makeFont();

in a header file without problems. The implementation of makeFont() will need to see the full definition of the class TTF_Font though. Hence in the implementation file you will need to include the file which defines the TTF_Font class. If you want to hide this implementation detail you may consider to put makeFont() into a library which you include into you project. This way your project needs not to include the header files defining TTF_Font unless you want to access members of this class for other reasons.

Concerning your Edit:

When you create a shared_ptr from a pointer then the shared_ptr will store internally how to delete that object. For this the shared_ptr needs to see the destructor of the type pointed to. Therefore, shared_ptr needs to see the struct definition even when no constructor is called.

Ralph Tandetzky
  • 22,780
  • 11
  • 73
  • 120
  • 1
    I'll check your answer when I get home, since I have the project on my desktop. I'll remember you were first ;) – Paweł Motyl Jul 15 '13 at 09:04
  • 1
    The typedef doesn't change anything. Keep in mind that I include the header with the same typedef, so it's already there. I tried to supply my own deleter to the shared_ptr constructor and that fixed the error, BUT when I put "delete p;" in that deleter, I got a warning about forward declaration of _TTF_Font class and a note that nor it's destructor nor the class-specific operator delete will be called. That's not a problem here, since there's a function in that library which in fact deletes the pointer, so I can use it, but in general case I still couldn't delete the pointer. – Paweł Motyl Jul 15 '13 at 18:02
  • That's what I've told you. But it's good that there's a library function which you can use for the custom deleter. – Ralph Tandetzky Jul 15 '13 at 20:01
  • @RalphTandetzky Hi, can you please say, if I want to add similar functionality regarding `incomplete` types in my homework ptr, what should I do? – VMAtm Dec 18 '15 at 12:08
  • @VMAtm What problem do you want to solve using incomplete types? – Ralph Tandetzky Dec 18 '15 at 13:35
  • @RalphTandetzky I need to implement sothing similar to shared_ptr (just a homework), and I need to be able to store a pointer to incomplete type without compilation errors. Compile errors should arise only if some operations on pointer are performed. – VMAtm Dec 18 '15 at 13:57
  • This is not the right place to give long answers to questions like that. You might ask a completely new question on the forum. That's what it's there for. Here's a very short answer: `shared_ptr` accomplishes the incomplete type trick by creating an object in the constructor which implements a virtual function from some base class. This function deletes the pointer passed into the constructor and is called in the destructor of the `shared_ptr`. The destructor of `shared_ptr` does not need to see the implementation and can be called by client code without seeing `T`'s definition. – Ralph Tandetzky Dec 19 '15 at 12:58
  • @PawełMotyl You should move your comment to an answer, this helped me too. – VP. Aug 23 '16 at 15:40