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 would one muzzle a full grown polar bear in the 13th century?
Don’t seats that recline flat defeat the purpose of having seatbelts?
Why does nature favour the Laplacian?
Rivers without rain
Why the difference in metal between 銀行 and お金?
Question relating to a number theoretic function
Will this character get back his Infinity Stone?
Stop and Take a Breath!
Short story about a planet with two sentient species
Unexpected email from Yorkshire Bank
Was it really necessary for the Lunar module LM to have 2 stages?
Minimum value of 4 digit number divided by sum of its digits
What is the strongest case that can be made in favour of the UK regaining some control over fishing policy after Brexit?
How can I place the product on a social media post better?
What's the polite way to say "I need to urinate"?
Has any spacecraft ever had the ability to directly communicate with civilian air traffic control?
How could Tony Stark make this in Endgame?
Pressure to defend the relevance of one's area of mathematics
Can solid acids and bases have pH values? If not, how are they classified as acids or bases?
How to delegate to implementing class
Executing a stored procedure which selects and inserts into tables in SQL Server
"The cow" OR "a cow" OR "cows" in this context
Is creating your own "experiment" considered cheating during a physics exam?
French for 'It must be my imagination'?
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 7 mins ago
answered 42 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