Archived

This topic is now archived and is closed to further replies.

Phlegmatic Weasel

C++: Double Inheritance from the same class...

Recommended Posts

Hello, As an exercise in graphics programming and OO design, I decided to try my hand at writing a simple library of widgets, together with the underlying framework. I am now getting to the system of events, and thought I would implement it using the publish-subscribe pattern, sort of like in Java, where you have an event-generator class, and an event-listener class. The listener registers with the generator, and when the event occurs, it is notified. Now, the problem is this: each event generator can notify several listeners that the event has occured. Therefore, the functionality for keeping track of the pointers to the listeners is the same for all generators. However, suppose I have several generators, like this:
class AbstractEventGenerator {
private:
	std::vector<AbstractEventListener *> listeners;

protected:
	AbstractEventGenerator() { /* ... */ }

	void AddListener(AbstractEventListener* listener) { 
		/* Add the listener to the listeners list */ 
	}

	virtual void FireEvent()=0;
};

class PushButtonEventGenerator : public AbstractEventGenerator {
public:
	PushButtonEventGenerator() { /* ... */ }

	void AddPushButtonEventListener(PushButtonEventListener* listener) {
		AddListener(listener);
	}

	void FireEvent() {
		/* Go through the list of listeners and call the appropriate function */
	}
};

class MouseClickEventGenerator : public AbstractEventGenerator {
public:
	MouseClickEventGenerator() { /* ... */ }

	void AddMouseClickEventListener(MouseClickEventListener* listener) {
		AddListener(listener);
	}

	void FireEvent() {
		/* Go through the list of listeners and call the appropriate function */
	}
};
And then I also have some sort of widget, that controls some aspect of the program both through a mouse-click and a button push. It is then defined like this:
class MysteryWidget: public PushButtonEventGenerator, public MouseClickEventGenerator { ... }; 
Okay, then I have the problem: the MysteryWidget class essentially derives twice from the AbstractEventGenerator class. So, the question is: would this mean that when I call AddPushButtonEventListener and when I call AddMouseClickEventListener, which in turn call the protected AddListener, it adds to the same listeners list? Or will this make two different copis of the listeners list, since I am deriving from AbstractEventGenerator through two different parents? And if they would add to the same vector, then any ideas on how to fix this (short of reimplementing the same functionality in every event generator) would be very welcome. I would try this myself now to see, but I don''t currently have access to a compiler - only the Internet, but I am in the middle of designing the class strcuture for the UI widgetset, so I would like to know if this would be a problem before I get too deep into the architecture based on this approach. Phlegmatic Weasel

Share this post


Link to post
Share on other sites
Fruny    1658
If you use virtual inheritance, all the instances of AbstractEventGenerator that MysteryWidget might inherit will be merged into a single one.

class PushButtonEventGenerator : public virtual AbstractEventGenerator { ... };

class MouseClickEventGenerator : public virtual AbstractEventGenerator { ... };

class MysteryWidget: public PushButtonEventGenerator, public MouseClickEventGenerator { ... };


Otherwise, depending on the base class that does the actual access, a different copy of AbstractEventGenerator will be used (each base class has one).

Direct access of AbstractEventGenerator from MysteryWidget will be flagged as ambiguous, unless you explicitely state which copy you want by specifying the correct base class, manually or with a using declaration.

void foo() { PushButtonEventGenerator::FireEvent(); };
void bar() { using PushButtonEventGenerator::FireEvent; FireEvent(); }


The using declaration applies to the symbol lookups that follow it in the scope it is placed in (file, class, function, block ...)

[edited by - Fruny on January 3, 2004 8:32:06 PM]

Share this post


Link to post
Share on other sites