How to delegate to implementing classIn C++, what is a virtual base class?How do you set, clear, and toggle a single bit?How do I iterate over the words of a string?Why can templates only be implemented in the header file?Safely override C++ virtual functionsDo ALL virtual functions need to be implemented in derived classes?How do you handle a “cannot instantiate abstract class” error in C++?Inheritance from empty base class in C++Can I have a virtual function that must be overridden from a non-abstract baseAbstract base class definitionHow to ensure that derivative classes implement particular methods, retaining standard layout?
How come there are so many candidates for the 2020 Democratic party presidential nomination?
How can the Zone of Truth spell be defeated without the caster knowing?
How do we know that ממחרת השבת means from the first day of pesach and not the seventh?
With a Canadian student visa, can I spend a night at Vancouver before continuing to Toronto?
How to figure out whether the data is sample data or population data apart from the client's information?
Will this character get back his Infinity Stone?
A Note on N!
How to stop co-workers from teasing me because I know Russian?
function to receive a character input and return date format (with incorrect input)
Smart diagram in Mathematica
Has any spacecraft ever had the ability to directly communicate with civilian air traffic control?
Counterexample: a pair of linearly ordered sets that are isomorphic to subsets of the other, but not isomorphic between them
How to make a pipeline wait for end-of-file or stop after an error?
Alternatives to Overleaf
How could Tony Stark make this in Endgame?
Help to reproduce a tcolorbox with a decoration
Why we can't write in air?
Can not tell colimits from limits
Killing undead fish underwater
Please, smoke with good manners
Any examples of headwear for races with animal ears?
Unexpected email from Yorkshire Bank
Why do 401k up to company match, then fill Roth IRA, then finish filling 401k?
How to verbalise code in Mathematica?
How to delegate to implementing class
In C++, what is a virtual base class?How do you set, clear, and toggle a single bit?How do I iterate over the words of a string?Why can templates only be implemented in the header file?Safely override C++ virtual functionsDo ALL virtual functions need to be implemented in derived classes?How do you handle a “cannot instantiate abstract class” error in C++?Inheritance from empty base class in C++Can I have a virtual function that must be overridden from a non-abstract baseAbstract base class definitionHow to ensure that derivative classes implement particular methods, retaining standard layout?
.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty height:90px;width:728px;box-sizing:border-box;
I have an abstract base class Node
, which is derived from an abstract Interface class IObservable
.
There is a several classes implementing the abstract IObservable
: SingleObservable
and MultiObservable
I want to create a class ObservableNode
, derived from the base Node
class and specify on its declaration which class to use for the implementation of the IObservable
interface.
I've added using ...
statements for every pure virtual method in IObservable
, referring to the methods in the implementation classes but I still get errors saying that ObservableNode
is an abstract class, missing the implementation of notifyObservers(IObject*)
.
If I add the parameter IObject*
to the using
statement I get an "expected ';' before '(' token" error
How can I solve this?
class IObservable
public:
virtual ~IObservable() ;
virtual void notifyObservers(IObject*) = 0;
;
class SingleObservable: public IObservable
public:
virtual ~SingleObservable() ;
void notifyObservers(IObject*) override
//some implementaiton
;
;
class MultiObservable: public IObservable
public:
virtual ~MultiObservable() ;
void notifyObservers(IObject*) override
//some other implementaiton
;
;
class Node: public IObservable
public:
virtual ~Node() ;
;
class ObservableNode: public Node, public SingleObservable
public:
virtual ~ObservableNode() ;
using SingleObservable::notifyObservers;
// using SingleObservable::notifyObservers(IObject*); // expected ';' before '(' token error
;
Node* node = new ObservableNode() // instantiating abstract class error, missing notifyObservers(IObject*) implementation
c++
add a comment |
I have an abstract base class Node
, which is derived from an abstract Interface class IObservable
.
There is a several classes implementing the abstract IObservable
: SingleObservable
and MultiObservable
I want to create a class ObservableNode
, derived from the base Node
class and specify on its declaration which class to use for the implementation of the IObservable
interface.
I've added using ...
statements for every pure virtual method in IObservable
, referring to the methods in the implementation classes but I still get errors saying that ObservableNode
is an abstract class, missing the implementation of notifyObservers(IObject*)
.
If I add the parameter IObject*
to the using
statement I get an "expected ';' before '(' token" error
How can I solve this?
class IObservable
public:
virtual ~IObservable() ;
virtual void notifyObservers(IObject*) = 0;
;
class SingleObservable: public IObservable
public:
virtual ~SingleObservable() ;
void notifyObservers(IObject*) override
//some implementaiton
;
;
class MultiObservable: public IObservable
public:
virtual ~MultiObservable() ;
void notifyObservers(IObject*) override
//some other implementaiton
;
;
class Node: public IObservable
public:
virtual ~Node() ;
;
class ObservableNode: public Node, public SingleObservable
public:
virtual ~ObservableNode() ;
using SingleObservable::notifyObservers;
// using SingleObservable::notifyObservers(IObject*); // expected ';' before '(' token error
;
Node* node = new ObservableNode() // instantiating abstract class error, missing notifyObservers(IObject*) implementation
c++
add a comment |
I have an abstract base class Node
, which is derived from an abstract Interface class IObservable
.
There is a several classes implementing the abstract IObservable
: SingleObservable
and MultiObservable
I want to create a class ObservableNode
, derived from the base Node
class and specify on its declaration which class to use for the implementation of the IObservable
interface.
I've added using ...
statements for every pure virtual method in IObservable
, referring to the methods in the implementation classes but I still get errors saying that ObservableNode
is an abstract class, missing the implementation of notifyObservers(IObject*)
.
If I add the parameter IObject*
to the using
statement I get an "expected ';' before '(' token" error
How can I solve this?
class IObservable
public:
virtual ~IObservable() ;
virtual void notifyObservers(IObject*) = 0;
;
class SingleObservable: public IObservable
public:
virtual ~SingleObservable() ;
void notifyObservers(IObject*) override
//some implementaiton
;
;
class MultiObservable: public IObservable
public:
virtual ~MultiObservable() ;
void notifyObservers(IObject*) override
//some other implementaiton
;
;
class Node: public IObservable
public:
virtual ~Node() ;
;
class ObservableNode: public Node, public SingleObservable
public:
virtual ~ObservableNode() ;
using SingleObservable::notifyObservers;
// using SingleObservable::notifyObservers(IObject*); // expected ';' before '(' token error
;
Node* node = new ObservableNode() // instantiating abstract class error, missing notifyObservers(IObject*) implementation
c++
I have an abstract base class Node
, which is derived from an abstract Interface class IObservable
.
There is a several classes implementing the abstract IObservable
: SingleObservable
and MultiObservable
I want to create a class ObservableNode
, derived from the base Node
class and specify on its declaration which class to use for the implementation of the IObservable
interface.
I've added using ...
statements for every pure virtual method in IObservable
, referring to the methods in the implementation classes but I still get errors saying that ObservableNode
is an abstract class, missing the implementation of notifyObservers(IObject*)
.
If I add the parameter IObject*
to the using
statement I get an "expected ';' before '(' token" error
How can I solve this?
class IObservable
public:
virtual ~IObservable() ;
virtual void notifyObservers(IObject*) = 0;
;
class SingleObservable: public IObservable
public:
virtual ~SingleObservable() ;
void notifyObservers(IObject*) override
//some implementaiton
;
;
class MultiObservable: public IObservable
public:
virtual ~MultiObservable() ;
void notifyObservers(IObject*) override
//some other implementaiton
;
;
class Node: public IObservable
public:
virtual ~Node() ;
;
class ObservableNode: public Node, public SingleObservable
public:
virtual ~ObservableNode() ;
using SingleObservable::notifyObservers;
// using SingleObservable::notifyObservers(IObject*); // expected ';' before '(' token error
;
Node* node = new ObservableNode() // instantiating abstract class error, missing notifyObservers(IObject*) implementation
c++
c++
edited 1 hour ago
Bascy
asked 1 hour ago
BascyBascy
99211034
99211034
add a comment |
add a comment |
2 Answers
2
active
oldest
votes
Your problem seems to be that you inherit Node
which is still abstract, and also causes to introduce the good old multimple inheritance vicious diamond problem. When I change your code like this, the error disappears:
class Node: public IObservable
public:
virtual ~Node() ;
// ** Added an implementation here **
void notifyObservers(IObject*) override
//some other implementaiton
;
;
class ObservableNode: public virtual Node, public virtual SingleObservable
// ^^^^^^^ ^^^^^^^
public:
virtual ~ObservableNode() ;
using SingleObservable::notifyObservers;
;
int main()
Node* node = new ObservableNode();
See it live on coliru.
@Scheff THX adopted it. Not to inheritNode
fromIObservable
would be certainly an alternative solution. You may still post that as an answer.
– πάντα ῥεῖ
1 hour ago
That indeed solved the problem, thanks! And indeed, I do want the IObservable interface in the Node definition
– Bascy
1 hour ago
1
Note that in this particular example,Node* node = new ObservableNode();
will meannode->notifyObservers(obj)
will invokeNode::notifyObservers(IObject*)
and notSingleObservable::notifyObservers(IObject*)
, which might be unexpected, considering we instantiate anObservableNode
object which specifiesusing SingleObservable::notifyObservers;
. What OP might possible want is to, inObservableNode
, define annotifyObservers(IObject*)
override which explictly forwards toSingleObservable::notifyObservers(IObject*)
.
– dfri
1 hour ago
1
... then a callnode->notifyObservers(obj)
will go down the vtable toObservableNode::notifyObservers(IObject*)
, and from there explicitly up to (by forwarding)SingleObservable::notifyObservers(IObject*)
.
– dfri
1 hour ago
1
@dfri THX for adding this information.
– πάντα ῥεῖ
1 hour ago
|
show 1 more comment
@πάντα ῥεῖ's answer describe one workaround, but possible this is not what OP is after here. Also, as my comment describe under the answer, the approach in the answer might give unexpected results e.g. when invoking node->notifyObservers(obj)
:
Note that in this particular example,
Node* node = new
will mean
ObservableNode();node->notifyObservers(obj)
will invoke
Node::notifyObservers(IObject*)
and not
SingleObservable::notifyObservers(IObject*)
, which might be
unexpected, considering we instantiate anObservableNode
object
which specifies usingSingleObservable::notifyObservers;
.
In OP's original code, we are suffering from multiple inheritance ambiguity, as we are not using virtual
inheritance when Node
and SingleObservable
(and MultiObservable
) derives from IObservable
:
class SingleObservable: public IObservable
public:
virtual ~SingleObservable() ;
void notifyObservers(IObject*) override
//some implementaiton
;
;
class Node: public IObservable
public:
virtual ~Node() ;
;
Meaning our the object's memory layout, w.r.t. inheritance, of ObservableNode
to looks like the following
IObservable IObservable
| |
Node SingleObservable
/
ObservableNode
whereas, in this context, we are likely to want an object's memory layout looking as follows
IObservable
/
Node SingleObservable
/
ObservableNode
If we were to correct this, Node
can stay abstract, and a call to node->notifyObservers(obj)
with node
as OP's example will result in invocation of SingleObservable::notifyObservers
, as might have been expected.
class Node: public virtual IObservable
// ↑↑↑↑↑↑↑
public:
virtual ~Node() ;
;
class SingleObservable: public virtual IObservable
// ↑↑↑↑↑↑↑
public:
virtual ~SingleObservable() ;
void notifyObservers(IObject*) override
std::cout << "SingleObservable::notifyObservers";
;
;
struct DummyObj : public IObject ;
int main()
Node* node = new ObservableNode();
DummyObj obj;
node->notifyObservers(obj); // SingleObservable::notifyObservers
Note that we not need virtual
inheritance for when ObservableNode
derives from Node
and SingleObservable
.
Finally, if we'd want Node
be non-abstract (specifically, to provide an override of void notifyObservers(IObject*)
), then ObservableNode
must provide it's own (final
) override of it, as we will otherwise inherit two final overrides of it in ObservableNode
(one from Node
and one from SingleObservable
). In this case, ObservableNode
could simply define its own override which explicitly calls the base class of choice, e.g.
class Node: public virtual IObservable
public:
virtual ~Node() ;
void notifyObservers(IObject*) override
std::cout << "Node::notifyObservers";
;
;
class SingleObservable: public virtual IObservable
public:
virtual ~SingleObservable() ;
void notifyObservers(IObject*) override
std::cout << "SingleObservable::notifyObservers";
;
;
class ObservableNode: public Node, public SingleObservable
public:
virtual ~ObservableNode() ;
// Non-ambiguous final override in ObservableNode.
// We could use `override` specifier here, but we might as well
// use `final`, if we are not expecting something to derive from ObservableNode.
void notifyObservers(IObject* obj) final
SingleObservable::notifyObservers(obj);
;
;
struct DummyObj : public IObject ;
int main()
Node* node = new ObservableNode();
DummyObj obj;
node->notifyObservers(obj); // SingleObservable::notifyObservers
See ISO C++ FAQ - Inheritance — Multiple and Virtual Inheritance for details on the diamond inheritance structure and virtual inheritance.
add a comment |
Your Answer
StackExchange.ifUsing("editor", function ()
StackExchange.using("externalEditor", function ()
StackExchange.using("snippets", function ()
StackExchange.snippets.init();
);
);
, "code-snippets");
StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "1"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);
else
createEditor();
);
function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader:
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
,
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);
);
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f55890369%2fhow-to-delegate-to-implementing-class%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
2 Answers
2
active
oldest
votes
2 Answers
2
active
oldest
votes
active
oldest
votes
active
oldest
votes
Your problem seems to be that you inherit Node
which is still abstract, and also causes to introduce the good old multimple inheritance vicious diamond problem. When I change your code like this, the error disappears:
class Node: public IObservable
public:
virtual ~Node() ;
// ** Added an implementation here **
void notifyObservers(IObject*) override
//some other implementaiton
;
;
class ObservableNode: public virtual Node, public virtual SingleObservable
// ^^^^^^^ ^^^^^^^
public:
virtual ~ObservableNode() ;
using SingleObservable::notifyObservers;
;
int main()
Node* node = new ObservableNode();
See it live on coliru.
@Scheff THX adopted it. Not to inheritNode
fromIObservable
would be certainly an alternative solution. You may still post that as an answer.
– πάντα ῥεῖ
1 hour ago
That indeed solved the problem, thanks! And indeed, I do want the IObservable interface in the Node definition
– Bascy
1 hour ago
1
Note that in this particular example,Node* node = new ObservableNode();
will meannode->notifyObservers(obj)
will invokeNode::notifyObservers(IObject*)
and notSingleObservable::notifyObservers(IObject*)
, which might be unexpected, considering we instantiate anObservableNode
object which specifiesusing SingleObservable::notifyObservers;
. What OP might possible want is to, inObservableNode
, define annotifyObservers(IObject*)
override which explictly forwards toSingleObservable::notifyObservers(IObject*)
.
– dfri
1 hour ago
1
... then a callnode->notifyObservers(obj)
will go down the vtable toObservableNode::notifyObservers(IObject*)
, and from there explicitly up to (by forwarding)SingleObservable::notifyObservers(IObject*)
.
– dfri
1 hour ago
1
@dfri THX for adding this information.
– πάντα ῥεῖ
1 hour ago
|
show 1 more comment
Your problem seems to be that you inherit Node
which is still abstract, and also causes to introduce the good old multimple inheritance vicious diamond problem. When I change your code like this, the error disappears:
class Node: public IObservable
public:
virtual ~Node() ;
// ** Added an implementation here **
void notifyObservers(IObject*) override
//some other implementaiton
;
;
class ObservableNode: public virtual Node, public virtual SingleObservable
// ^^^^^^^ ^^^^^^^
public:
virtual ~ObservableNode() ;
using SingleObservable::notifyObservers;
;
int main()
Node* node = new ObservableNode();
See it live on coliru.
@Scheff THX adopted it. Not to inheritNode
fromIObservable
would be certainly an alternative solution. You may still post that as an answer.
– πάντα ῥεῖ
1 hour ago
That indeed solved the problem, thanks! And indeed, I do want the IObservable interface in the Node definition
– Bascy
1 hour ago
1
Note that in this particular example,Node* node = new ObservableNode();
will meannode->notifyObservers(obj)
will invokeNode::notifyObservers(IObject*)
and notSingleObservable::notifyObservers(IObject*)
, which might be unexpected, considering we instantiate anObservableNode
object which specifiesusing SingleObservable::notifyObservers;
. What OP might possible want is to, inObservableNode
, define annotifyObservers(IObject*)
override which explictly forwards toSingleObservable::notifyObservers(IObject*)
.
– dfri
1 hour ago
1
... then a callnode->notifyObservers(obj)
will go down the vtable toObservableNode::notifyObservers(IObject*)
, and from there explicitly up to (by forwarding)SingleObservable::notifyObservers(IObject*)
.
– dfri
1 hour ago
1
@dfri THX for adding this information.
– πάντα ῥεῖ
1 hour ago
|
show 1 more comment
Your problem seems to be that you inherit Node
which is still abstract, and also causes to introduce the good old multimple inheritance vicious diamond problem. When I change your code like this, the error disappears:
class Node: public IObservable
public:
virtual ~Node() ;
// ** Added an implementation here **
void notifyObservers(IObject*) override
//some other implementaiton
;
;
class ObservableNode: public virtual Node, public virtual SingleObservable
// ^^^^^^^ ^^^^^^^
public:
virtual ~ObservableNode() ;
using SingleObservable::notifyObservers;
;
int main()
Node* node = new ObservableNode();
See it live on coliru.
Your problem seems to be that you inherit Node
which is still abstract, and also causes to introduce the good old multimple inheritance vicious diamond problem. When I change your code like this, the error disappears:
class Node: public IObservable
public:
virtual ~Node() ;
// ** Added an implementation here **
void notifyObservers(IObject*) override
//some other implementaiton
;
;
class ObservableNode: public virtual Node, public virtual SingleObservable
// ^^^^^^^ ^^^^^^^
public:
virtual ~ObservableNode() ;
using SingleObservable::notifyObservers;
;
int main()
Node* node = new ObservableNode();
See it live on coliru.
edited 1 hour ago
answered 1 hour ago
πάντα ῥεῖπάντα ῥεῖ
74.6k1078146
74.6k1078146
@Scheff THX adopted it. Not to inheritNode
fromIObservable
would be certainly an alternative solution. You may still post that as an answer.
– πάντα ῥεῖ
1 hour ago
That indeed solved the problem, thanks! And indeed, I do want the IObservable interface in the Node definition
– Bascy
1 hour ago
1
Note that in this particular example,Node* node = new ObservableNode();
will meannode->notifyObservers(obj)
will invokeNode::notifyObservers(IObject*)
and notSingleObservable::notifyObservers(IObject*)
, which might be unexpected, considering we instantiate anObservableNode
object which specifiesusing SingleObservable::notifyObservers;
. What OP might possible want is to, inObservableNode
, define annotifyObservers(IObject*)
override which explictly forwards toSingleObservable::notifyObservers(IObject*)
.
– dfri
1 hour ago
1
... then a callnode->notifyObservers(obj)
will go down the vtable toObservableNode::notifyObservers(IObject*)
, and from there explicitly up to (by forwarding)SingleObservable::notifyObservers(IObject*)
.
– dfri
1 hour ago
1
@dfri THX for adding this information.
– πάντα ῥεῖ
1 hour ago
|
show 1 more comment
@Scheff THX adopted it. Not to inheritNode
fromIObservable
would be certainly an alternative solution. You may still post that as an answer.
– πάντα ῥεῖ
1 hour ago
That indeed solved the problem, thanks! And indeed, I do want the IObservable interface in the Node definition
– Bascy
1 hour ago
1
Note that in this particular example,Node* node = new ObservableNode();
will meannode->notifyObservers(obj)
will invokeNode::notifyObservers(IObject*)
and notSingleObservable::notifyObservers(IObject*)
, which might be unexpected, considering we instantiate anObservableNode
object which specifiesusing SingleObservable::notifyObservers;
. What OP might possible want is to, inObservableNode
, define annotifyObservers(IObject*)
override which explictly forwards toSingleObservable::notifyObservers(IObject*)
.
– dfri
1 hour ago
1
... then a callnode->notifyObservers(obj)
will go down the vtable toObservableNode::notifyObservers(IObject*)
, and from there explicitly up to (by forwarding)SingleObservable::notifyObservers(IObject*)
.
– dfri
1 hour ago
1
@dfri THX for adding this information.
– πάντα ῥεῖ
1 hour ago
@Scheff THX adopted it. Not to inherit
Node
from IObservable
would be certainly an alternative solution. You may still post that as an answer.– πάντα ῥεῖ
1 hour ago
@Scheff THX adopted it. Not to inherit
Node
from IObservable
would be certainly an alternative solution. You may still post that as an answer.– πάντα ῥεῖ
1 hour ago
That indeed solved the problem, thanks! And indeed, I do want the IObservable interface in the Node definition
– Bascy
1 hour ago
That indeed solved the problem, thanks! And indeed, I do want the IObservable interface in the Node definition
– Bascy
1 hour ago
1
1
Note that in this particular example,
Node* node = new ObservableNode();
will mean node->notifyObservers(obj)
will invoke Node::notifyObservers(IObject*)
and not SingleObservable::notifyObservers(IObject*)
, which might be unexpected, considering we instantiate an ObservableNode
object which specifies using SingleObservable::notifyObservers;
. What OP might possible want is to, in ObservableNode
, define an notifyObservers(IObject*)
override which explictly forwards to SingleObservable::notifyObservers(IObject*)
.– dfri
1 hour ago
Note that in this particular example,
Node* node = new ObservableNode();
will mean node->notifyObservers(obj)
will invoke Node::notifyObservers(IObject*)
and not SingleObservable::notifyObservers(IObject*)
, which might be unexpected, considering we instantiate an ObservableNode
object which specifies using SingleObservable::notifyObservers;
. What OP might possible want is to, in ObservableNode
, define an notifyObservers(IObject*)
override which explictly forwards to SingleObservable::notifyObservers(IObject*)
.– dfri
1 hour ago
1
1
... then a call
node->notifyObservers(obj)
will go down the vtable to ObservableNode::notifyObservers(IObject*)
, and from there explicitly up to (by forwarding) SingleObservable::notifyObservers(IObject*)
.– dfri
1 hour ago
... then a call
node->notifyObservers(obj)
will go down the vtable to ObservableNode::notifyObservers(IObject*)
, and from there explicitly up to (by forwarding) SingleObservable::notifyObservers(IObject*)
.– dfri
1 hour ago
1
1
@dfri THX for adding this information.
– πάντα ῥεῖ
1 hour ago
@dfri THX for adding this information.
– πάντα ῥεῖ
1 hour ago
|
show 1 more comment
@πάντα ῥεῖ's answer describe one workaround, but possible this is not what OP is after here. Also, as my comment describe under the answer, the approach in the answer might give unexpected results e.g. when invoking node->notifyObservers(obj)
:
Note that in this particular example,
Node* node = new
will mean
ObservableNode();node->notifyObservers(obj)
will invoke
Node::notifyObservers(IObject*)
and not
SingleObservable::notifyObservers(IObject*)
, which might be
unexpected, considering we instantiate anObservableNode
object
which specifies usingSingleObservable::notifyObservers;
.
In OP's original code, we are suffering from multiple inheritance ambiguity, as we are not using virtual
inheritance when Node
and SingleObservable
(and MultiObservable
) derives from IObservable
:
class SingleObservable: public IObservable
public:
virtual ~SingleObservable() ;
void notifyObservers(IObject*) override
//some implementaiton
;
;
class Node: public IObservable
public:
virtual ~Node() ;
;
Meaning our the object's memory layout, w.r.t. inheritance, of ObservableNode
to looks like the following
IObservable IObservable
| |
Node SingleObservable
/
ObservableNode
whereas, in this context, we are likely to want an object's memory layout looking as follows
IObservable
/
Node SingleObservable
/
ObservableNode
If we were to correct this, Node
can stay abstract, and a call to node->notifyObservers(obj)
with node
as OP's example will result in invocation of SingleObservable::notifyObservers
, as might have been expected.
class Node: public virtual IObservable
// ↑↑↑↑↑↑↑
public:
virtual ~Node() ;
;
class SingleObservable: public virtual IObservable
// ↑↑↑↑↑↑↑
public:
virtual ~SingleObservable() ;
void notifyObservers(IObject*) override
std::cout << "SingleObservable::notifyObservers";
;
;
struct DummyObj : public IObject ;
int main()
Node* node = new ObservableNode();
DummyObj obj;
node->notifyObservers(obj); // SingleObservable::notifyObservers
Note that we not need virtual
inheritance for when ObservableNode
derives from Node
and SingleObservable
.
Finally, if we'd want Node
be non-abstract (specifically, to provide an override of void notifyObservers(IObject*)
), then ObservableNode
must provide it's own (final
) override of it, as we will otherwise inherit two final overrides of it in ObservableNode
(one from Node
and one from SingleObservable
). In this case, ObservableNode
could simply define its own override which explicitly calls the base class of choice, e.g.
class Node: public virtual IObservable
public:
virtual ~Node() ;
void notifyObservers(IObject*) override
std::cout << "Node::notifyObservers";
;
;
class SingleObservable: public virtual IObservable
public:
virtual ~SingleObservable() ;
void notifyObservers(IObject*) override
std::cout << "SingleObservable::notifyObservers";
;
;
class ObservableNode: public Node, public SingleObservable
public:
virtual ~ObservableNode() ;
// Non-ambiguous final override in ObservableNode.
// We could use `override` specifier here, but we might as well
// use `final`, if we are not expecting something to derive from ObservableNode.
void notifyObservers(IObject* obj) final
SingleObservable::notifyObservers(obj);
;
;
struct DummyObj : public IObject ;
int main()
Node* node = new ObservableNode();
DummyObj obj;
node->notifyObservers(obj); // SingleObservable::notifyObservers
See ISO C++ FAQ - Inheritance — Multiple and Virtual Inheritance for details on the diamond inheritance structure and virtual inheritance.
add a comment |
@πάντα ῥεῖ's answer describe one workaround, but possible this is not what OP is after here. Also, as my comment describe under the answer, the approach in the answer might give unexpected results e.g. when invoking node->notifyObservers(obj)
:
Note that in this particular example,
Node* node = new
will mean
ObservableNode();node->notifyObservers(obj)
will invoke
Node::notifyObservers(IObject*)
and not
SingleObservable::notifyObservers(IObject*)
, which might be
unexpected, considering we instantiate anObservableNode
object
which specifies usingSingleObservable::notifyObservers;
.
In OP's original code, we are suffering from multiple inheritance ambiguity, as we are not using virtual
inheritance when Node
and SingleObservable
(and MultiObservable
) derives from IObservable
:
class SingleObservable: public IObservable
public:
virtual ~SingleObservable() ;
void notifyObservers(IObject*) override
//some implementaiton
;
;
class Node: public IObservable
public:
virtual ~Node() ;
;
Meaning our the object's memory layout, w.r.t. inheritance, of ObservableNode
to looks like the following
IObservable IObservable
| |
Node SingleObservable
/
ObservableNode
whereas, in this context, we are likely to want an object's memory layout looking as follows
IObservable
/
Node SingleObservable
/
ObservableNode
If we were to correct this, Node
can stay abstract, and a call to node->notifyObservers(obj)
with node
as OP's example will result in invocation of SingleObservable::notifyObservers
, as might have been expected.
class Node: public virtual IObservable
// ↑↑↑↑↑↑↑
public:
virtual ~Node() ;
;
class SingleObservable: public virtual IObservable
// ↑↑↑↑↑↑↑
public:
virtual ~SingleObservable() ;
void notifyObservers(IObject*) override
std::cout << "SingleObservable::notifyObservers";
;
;
struct DummyObj : public IObject ;
int main()
Node* node = new ObservableNode();
DummyObj obj;
node->notifyObservers(obj); // SingleObservable::notifyObservers
Note that we not need virtual
inheritance for when ObservableNode
derives from Node
and SingleObservable
.
Finally, if we'd want Node
be non-abstract (specifically, to provide an override of void notifyObservers(IObject*)
), then ObservableNode
must provide it's own (final
) override of it, as we will otherwise inherit two final overrides of it in ObservableNode
(one from Node
and one from SingleObservable
). In this case, ObservableNode
could simply define its own override which explicitly calls the base class of choice, e.g.
class Node: public virtual IObservable
public:
virtual ~Node() ;
void notifyObservers(IObject*) override
std::cout << "Node::notifyObservers";
;
;
class SingleObservable: public virtual IObservable
public:
virtual ~SingleObservable() ;
void notifyObservers(IObject*) override
std::cout << "SingleObservable::notifyObservers";
;
;
class ObservableNode: public Node, public SingleObservable
public:
virtual ~ObservableNode() ;
// Non-ambiguous final override in ObservableNode.
// We could use `override` specifier here, but we might as well
// use `final`, if we are not expecting something to derive from ObservableNode.
void notifyObservers(IObject* obj) final
SingleObservable::notifyObservers(obj);
;
;
struct DummyObj : public IObject ;
int main()
Node* node = new ObservableNode();
DummyObj obj;
node->notifyObservers(obj); // SingleObservable::notifyObservers
See ISO C++ FAQ - Inheritance — Multiple and Virtual Inheritance for details on the diamond inheritance structure and virtual inheritance.
add a comment |
@πάντα ῥεῖ's answer describe one workaround, but possible this is not what OP is after here. Also, as my comment describe under the answer, the approach in the answer might give unexpected results e.g. when invoking node->notifyObservers(obj)
:
Note that in this particular example,
Node* node = new
will mean
ObservableNode();node->notifyObservers(obj)
will invoke
Node::notifyObservers(IObject*)
and not
SingleObservable::notifyObservers(IObject*)
, which might be
unexpected, considering we instantiate anObservableNode
object
which specifies usingSingleObservable::notifyObservers;
.
In OP's original code, we are suffering from multiple inheritance ambiguity, as we are not using virtual
inheritance when Node
and SingleObservable
(and MultiObservable
) derives from IObservable
:
class SingleObservable: public IObservable
public:
virtual ~SingleObservable() ;
void notifyObservers(IObject*) override
//some implementaiton
;
;
class Node: public IObservable
public:
virtual ~Node() ;
;
Meaning our the object's memory layout, w.r.t. inheritance, of ObservableNode
to looks like the following
IObservable IObservable
| |
Node SingleObservable
/
ObservableNode
whereas, in this context, we are likely to want an object's memory layout looking as follows
IObservable
/
Node SingleObservable
/
ObservableNode
If we were to correct this, Node
can stay abstract, and a call to node->notifyObservers(obj)
with node
as OP's example will result in invocation of SingleObservable::notifyObservers
, as might have been expected.
class Node: public virtual IObservable
// ↑↑↑↑↑↑↑
public:
virtual ~Node() ;
;
class SingleObservable: public virtual IObservable
// ↑↑↑↑↑↑↑
public:
virtual ~SingleObservable() ;
void notifyObservers(IObject*) override
std::cout << "SingleObservable::notifyObservers";
;
;
struct DummyObj : public IObject ;
int main()
Node* node = new ObservableNode();
DummyObj obj;
node->notifyObservers(obj); // SingleObservable::notifyObservers
Note that we not need virtual
inheritance for when ObservableNode
derives from Node
and SingleObservable
.
Finally, if we'd want Node
be non-abstract (specifically, to provide an override of void notifyObservers(IObject*)
), then ObservableNode
must provide it's own (final
) override of it, as we will otherwise inherit two final overrides of it in ObservableNode
(one from Node
and one from SingleObservable
). In this case, ObservableNode
could simply define its own override which explicitly calls the base class of choice, e.g.
class Node: public virtual IObservable
public:
virtual ~Node() ;
void notifyObservers(IObject*) override
std::cout << "Node::notifyObservers";
;
;
class SingleObservable: public virtual IObservable
public:
virtual ~SingleObservable() ;
void notifyObservers(IObject*) override
std::cout << "SingleObservable::notifyObservers";
;
;
class ObservableNode: public Node, public SingleObservable
public:
virtual ~ObservableNode() ;
// Non-ambiguous final override in ObservableNode.
// We could use `override` specifier here, but we might as well
// use `final`, if we are not expecting something to derive from ObservableNode.
void notifyObservers(IObject* obj) final
SingleObservable::notifyObservers(obj);
;
;
struct DummyObj : public IObject ;
int main()
Node* node = new ObservableNode();
DummyObj obj;
node->notifyObservers(obj); // SingleObservable::notifyObservers
See ISO C++ FAQ - Inheritance — Multiple and Virtual Inheritance for details on the diamond inheritance structure and virtual inheritance.
@πάντα ῥεῖ's answer describe one workaround, but possible this is not what OP is after here. Also, as my comment describe under the answer, the approach in the answer might give unexpected results e.g. when invoking node->notifyObservers(obj)
:
Note that in this particular example,
Node* node = new
will mean
ObservableNode();node->notifyObservers(obj)
will invoke
Node::notifyObservers(IObject*)
and not
SingleObservable::notifyObservers(IObject*)
, which might be
unexpected, considering we instantiate anObservableNode
object
which specifies usingSingleObservable::notifyObservers;
.
In OP's original code, we are suffering from multiple inheritance ambiguity, as we are not using virtual
inheritance when Node
and SingleObservable
(and MultiObservable
) derives from IObservable
:
class SingleObservable: public IObservable
public:
virtual ~SingleObservable() ;
void notifyObservers(IObject*) override
//some implementaiton
;
;
class Node: public IObservable
public:
virtual ~Node() ;
;
Meaning our the object's memory layout, w.r.t. inheritance, of ObservableNode
to looks like the following
IObservable IObservable
| |
Node SingleObservable
/
ObservableNode
whereas, in this context, we are likely to want an object's memory layout looking as follows
IObservable
/
Node SingleObservable
/
ObservableNode
If we were to correct this, Node
can stay abstract, and a call to node->notifyObservers(obj)
with node
as OP's example will result in invocation of SingleObservable::notifyObservers
, as might have been expected.
class Node: public virtual IObservable
// ↑↑↑↑↑↑↑
public:
virtual ~Node() ;
;
class SingleObservable: public virtual IObservable
// ↑↑↑↑↑↑↑
public:
virtual ~SingleObservable() ;
void notifyObservers(IObject*) override
std::cout << "SingleObservable::notifyObservers";
;
;
struct DummyObj : public IObject ;
int main()
Node* node = new ObservableNode();
DummyObj obj;
node->notifyObservers(obj); // SingleObservable::notifyObservers
Note that we not need virtual
inheritance for when ObservableNode
derives from Node
and SingleObservable
.
Finally, if we'd want Node
be non-abstract (specifically, to provide an override of void notifyObservers(IObject*)
), then ObservableNode
must provide it's own (final
) override of it, as we will otherwise inherit two final overrides of it in ObservableNode
(one from Node
and one from SingleObservable
). In this case, ObservableNode
could simply define its own override which explicitly calls the base class of choice, e.g.
class Node: public virtual IObservable
public:
virtual ~Node() ;
void notifyObservers(IObject*) override
std::cout << "Node::notifyObservers";
;
;
class SingleObservable: public virtual IObservable
public:
virtual ~SingleObservable() ;
void notifyObservers(IObject*) override
std::cout << "SingleObservable::notifyObservers";
;
;
class ObservableNode: public Node, public SingleObservable
public:
virtual ~ObservableNode() ;
// Non-ambiguous final override in ObservableNode.
// We could use `override` specifier here, but we might as well
// use `final`, if we are not expecting something to derive from ObservableNode.
void notifyObservers(IObject* obj) final
SingleObservable::notifyObservers(obj);
;
;
struct DummyObj : public IObject ;
int main()
Node* node = new ObservableNode();
DummyObj obj;
node->notifyObservers(obj); // SingleObservable::notifyObservers
See ISO C++ FAQ - Inheritance — Multiple and Virtual Inheritance for details on the diamond inheritance structure and virtual inheritance.
edited 13 mins ago
answered 48 mins ago
dfridfri
36.5k462103
36.5k462103
add a comment |
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f55890369%2fhow-to-delegate-to-implementing-class%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown