Syntax for non-virtual multiple inheritence

Started by
5 comments, last by Schrompf 14 years, 10 months ago
Hi. Please see this C++ example of what I'm trying to do

struct A {
	int x;
	A (int y) : x(y) {}
	void foo () {std::cout << x;}
};

struct B : public A {
	B () : A(1) {}
};

struct C : public A {
	C () : A(2) {}
};

struct D : public B, public C {
	void foo () {
		B :: A :: foo ();	// Line 19
		C :: A :: foo ();	// Line 20
		(B::A)(*this) . foo ();	// Line 21
		(C::A)(*this) . foo ();	// Line 22
	}
};

int main () {
	D d;
	d.foo ();
}

I figured both these methods of disambiguating would be valid, but neither are:
Quote:/tmp/x.cpp: In member function ‘void D::foo()’: /tmp/x.cpp:19: error: cannot call member function ‘void A::foo()’ without object /tmp/x.cpp:20: error: cannot call member function ‘void A::foo()’ without object /tmp/x.cpp:21: error: invalid use of void expression /tmp/x.cpp:22: error: invalid use of void expression
And yes, I *DO* want to keep multiple instances of A in D. So what syntax lets me choose between multiple *:A::foo invocations? Thanks
Advertisement
Don't disambiguate where you don't have to:
#include <iostream>struct A {	int x;	A (int y) : x(y) {}	void foo () {std::cout << x;}};struct B : public A {	B () : A(1) {}};struct C : public A {	C () : A(2) {}};struct D : public B, public C {	void foo () {		B :: foo ();	// Line 19		C :: foo ();	// Line 20			}};int main () {	D d;	d.foo ();}
Sorry, perhaps I oversimplified:
struct A {	int x;	A (int y) : x(y) {}	void foo () {std::cout << x;}};struct B : public A {	B () : A(1) {}	void foo () {std::cout << 'b';}};struct C : public A {	C () : A(2) {}	void foo () {std::cout << 'c';}};struct D : public B, public C {	void foo () {		B :: foo ();		C :: foo ();		B :: A :: foo ();		C :: A :: foo ();		(B::A)(*this) . foo ();		(C::A)(*this) . foo ();	}};int main () {	D d;	d.foo ();}

I'm expecting this to print "bc1212"
E.g.:

(B::A)(*this) . foo ();(C::A)(*this) . foo ();


Can't work:
-> it's the equivalent of (C::A)((*this) . foo ()), but foo() is of type void

	void foo () {		B * b = this;		C * c = this;		b->foo();		c->foo();		static_cast<A *>(b)->foo();		static_cast<A *>(c)->foo();	}


[Edited by - Sneftel on June 30, 2009 10:36:25 AM]
		(B::A)(*this) . foo ();	// Line 21		(C::A)(*this) . foo ();	// Line 22

That is bad mojo. You are taking your *this, and casting it to a distinct instance of B::A.

Code that isn't bad mojo yet is similar in flow would be:
(B*)(this)->foo();(C*)(this)->foo();

with the note that using C-style casts is massive overkill and should be avoided. As in this case you can do it implicitly, do it -- see SiCrane's post. Note that SiCrane's post has a formatting bug -- the forum ate the template arguments to the static_casts (where where A* I'm guessing).
Maybe the problem is over-simplified here, but why exactly do you want to use inheritance at all? What about this instead:

struct A {	int x;	A (int y) : x(y) {}	void foo () {std::cout << x;}};struct B : public A {	B () : A(1) {}};struct C : public A {	C () : A(2) {}};struct D {        B b;        C c;	void foo () {		b.foo();	// Line 19		c.foo ();	// Line 20                static_cast<A*> (&b)->foo();  // Line 21		static_cast<A*> (&c)->foo();  // Line 22	}};int main () {	D d;	d.foo ();}


Should do the trick in my books. It's even the same memory layout as far as I can tell.
----------
Gonna try that "Indie" stuff I keep hearing about. Let's start with Splatter.

This topic is closed to new replies.

Advertisement