forward declaring with inheritance information
Asked Answered
L

2

6

This compiles fine, although I wouldn't want to try running it just yet. However ...

//class base;
//class derived;
//class derived : public base;

class base {};
class derived : public base {};

class other
{
    public:
        void func() {base1 = derived1;}
        base* base1;
        derived* derived1;
};

void main()
{
}

... moving the class other to above the definition of base and derived for which there is a similar thing I must do in a program of myne causes compile errors.

The obvious solution is to forward declare base and derived shown commented out at the top of the code, however this causes a can't convert between base* and derived* error. Attempting to forward declare including the inheritance information dosn't work either.

Lycian answered 16/1, 2011 at 20:22 Comment(0)
K
9

This should work. You need to move other up

BUT declare func below. That way func is able to "see" that derived is of type base.

e.g.,

class base;
class derived;
//class derived : public base;

class other
{
    public:
        void func();
        base* base1;
        derived* derived1;
};

class base {};
class derived : public base {};

void other::func() { base1 = derived1; }
Kovno answered 16/1, 2011 at 20:26 Comment(1)
Excellent. Worked well, in this and in the program with the real problem. I'm hoping that this will be the end of the problem for good.Lycian
D
4

There is no syntax for forward-declaring two classes and specifying that one inherits from the other. This is because inheritance can be complex (multiple and/or virtual), so the assignment base1 = derived1 might involve some arithmetic, and it's difficult/impossible for the compiler to generate that arithmetic when it only knows that derived inherits from base.

So, to solve your problem, you can make func not inline (see the answer from AbstractDissonance), or, if you absolutely need it to be inline, use reinterpret_cast:

class base;
class derived;

class other
{
    public:
        void func() {base1 = reinterpret_cast<base*>(derived1);}
        base* base1;
        derived* derived1;
};

This is bad because it is not guaranteed to work by the C++ standard, and it will almost certainly not work if you use multiple/virtual inheritance. Use this only if func has to be as fast as possible (i.e. inline), and if you don't need your code to be portable.

Decastro answered 16/1, 2011 at 20:38 Comment(1)
I'll bear this in mind but use the other solution for now. It's usefull to know. I didn't realise that the reinterpret_cast could be used in this way.Lycian

© 2022 - 2024 — McMap. All rights reserved.