Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Dealing with incomplete types

I have two classes: one of them has an incomplete type, and the second needs to use that incomplete type. Is there any way to reference an "external type", in a manner similar to how you reference an external object?


Edit: Details about the structure of my classes.

Unfortunately I can't use pointers either. My code looks something like this:

class CompleteA {
  private:
    friend CompleteB;
    struct IncompleteA;
    boost::shared_ptr<IncompleteA> data_;
};

class CompleteB {
   public:
     void SomeFct(CompleteA& a) {
        // I need to access a member of the incomplete type
        a.data_->someMember;
     }
};

I could have a separate header and source files pair but the that would be a bit of an overkill in my case. The incomplete type is just a struct with one member; I use it to hide the implementation. (However, if there's no other option, I will resort to having a separate header...)

About my use of friend, please ignore that and concentrate on what I'm asking help with. I've pondered about whether or not I should use friend here and I've come to the conclusion that using getters (instead of a friend) would expose the implementation.

like image 271
Paul Manta Avatar asked Aug 26 '26 01:08

Paul Manta


1 Answers

Use forward declaration.

In your yourotherclass.h:

class IncompleteClass;

class YourOtherClass
{
    IncompleteClass* member;
};

In your yourotherclass.cpp you will actually need to include the incompleteclass.h in order to be able to use the pointer.

Edit: responding to your details:

If you want to hide the implementation, create a separate (friend) class for that and reference that:

class CompleteAImpl
{
    friend CompleteA;
    // data, members, etc. that you intend to hide
};

class CompleteA
{
    CompleteAImpl* priv; // or shared_ptr if you want
};

I think you wanted to do something like this. The problem with your implementation is that in order to reference a member a struct/class the compiler needs to to know the size of that member and the preceding members. You can cast your (a.data_ + sizeof(all preceding members)) to the type of someMember and dereference that; but it's an ugly and unsafe solution.

like image 108
Tamás Szelei Avatar answered Aug 27 '26 14:08

Tamás Szelei



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!