Multiple Inheritance

Pages: 12
I have a struct with multiple inheritance.

1
2
3
4
5
6
7
8
9
10
11
12

struct RS_A {
	int count;
};

struct RS_B {
	int * values;
};

struct RS_AB : public RS_A, RS_B {
};


This snippet of code errors:

1
2
3
4
5
6
7
8

RS_A * s;
s = new RS_AB;

//.....//

((RS_B *) s)->values[i] = 1; //error


What's wrong, please?

(I know I could restructure my code but I would like to know the answer to this specific issue)
Why are you casting? I find myself repeating this, do not cast. You're overriding the type system, which usually means you're doing something wrong.

RS_B is not publicly inherited in your example.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
struct RS_A
{
        int count;
};

struct RS_B
{
        int* value;
};

struct RS_AB : public RS_A, public RS_B
{
};

int main()
{
        RS_AB* pAB = new RS_AB;
        pAB->value = 0;

        return 0;
}
Last edited on
If I change the line to this, it works fine.

1
2
3

((RS_AB *) s)->values[i] = 1;


The problem is that I have lots of versions of RS_AB.

The only shared inheritance between all the versions of RS_AB is the use of RS_A.

Last edited on
Why are you casting?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47

struct RS_A {
	int count;
};

struct RS_B {
	int * values;
};

struct RS_C {
	int * values;
};

struct RS_D {
	int * values;
};

struct RS_E {
};

struct RS_sAB : public RS_A, RS_B {
};

struct RS_sAC : public RS_A, RS_C {
};

struct RS_sADE : public RS_A, RS_D, RS_E {
};

struct myStruct {
	RS_A * s;

	void somefunc() {
		((RS_C) s).values[0] = 0;
	};
};

void main() {
	mystruct temp;
	temp.s = new RS_sAC;
	temp.somefunc; //i would only call this when s is a class that inherits from C, like now.

	mystruct temp2;
	temp.s = new RS_sAB;
	//not called
}

(look at new example)

I am casting because s is RS_A which isnt a type of RS_C.

Last edited on
You have to be extremely careful when using multiple inheritance.

It's generally accepted that you should not multiply inherit implementation. However, flavours/mixins are a legitimate pattern, and there are other patterns that use it.

Having said all that, I still can't see why you need to cast. I'm not so sure about the design. I would probably like to see the UML class diagram, but that's clearly not necessary here.
kbw wrote:
RS_B is not publicly inherited in your example.

It is publicly inherited because he use struct.
I need the cast because if I didn't have it I would get an error because RS_A doesn't have a method called somefunc()

I also don't understand this. None of the RS types has a member function named somefunc().
Last edited on
mystruct does?
I still don't see why you think you need a cast.
1
2
3
4
5
6
7
struct myStruct {
	RS_A * s;

	void somefunc() {
		// RS_A doesn't have member value, and casting won't produce one
	}
};

Last edited on
RS_A doesn't have a member called values so that does not work. If you want s to point to something that is not a RS_A object why do you make s type RS_A*?

I still don't see why you think you need a cast.


RS_A doesnt have variable values

edit: (This related to the code before your edit)
Last edited on

RS_A doesn't have a member called values so that does not work. If you want s to point to something that is not a RS_A object why do you make s type RS_A*?


I could have declared it as a void pointer, but the problem would still exist, no?

I made it RS_A because they are all of type RS_A... its the one struct they all share.


Why doesn't casting a pointer, as a struct the class inherits from, find elements within it when multiple inheritance is used?
That's right.

Your code fails to compile without the cast because the compiler is telling you that you have done something wrong. And you are. RS_A doesn't have a member value and pretending it does with a cast won't make it true.

You're attempting to override the compiler's static type checking, and if you succeed, you'll have a run time crash.
I (kinda) get ya, but I need to understand this a bit better so I will continue.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47

struct RS_A {
	int count;
};

struct RS_B {
	int * values;
};

struct RS_C {
	int * values;
};

struct RS_D {
	int * values;
};

struct RS_E {
};

struct RS_sAB : public RS_A, RS_B {
};

struct RS_sAC : public RS_A, RS_C {
};

struct RS_sADE : public RS_A, RS_D, RS_E {
};

struct myStruct {
	void * s;

	void somefunc() {
		((RS_C) s).values[0] = 0;
	};
};

void main() {
	mystruct temp;
	temp.s = new RS_sAC;
	temp.somefunc; //i would only call this when s is a class that inherits from C, like now.

	mystruct temp2;
	temp.s = new RS_sAB;
	//not called
}


What about this? It's now a void pointer.
Last edited on
i would only call this when s is a class that inherits from C, like now.

Then why not make s type RS_C* and get rid of the cast?

Then why not make s type RS_C* and get rid of the cast?


This code comes from a much bigger piece of code.

There are other functions in mystruct that are only called when s contains an instance of RS_B or RS_D or RS_E or RS_F or...
I can't get my head around why casting a pointer would make such a difference. Surely its just a pointer (with type info). Why does casting it not just make it the appropriate pointer type???
Pages: 12