How to use functions from derived class without adding them to the base class
This is very likely a silly question, but I can't seem to figure out if this is at all possible and if it should actually be done.
Say some code relies a lot on using a certain virtual base class acting as an interface and then deriving several subclasses that implements the virtual methods the base class. Is it possible to use functionality not exsisting in the base class (interface) below without completely disregarding the solid principles, when the rest of the program must not see anything but the base class "interface"? Like in the example below, is it possible to use bar() from the B class inside the function that only knows of A? And should I just add bar() to the "interface" instead?
// Base class - "interface"
Class A
{
public:
virtual int foo();
}
// Derived class - implementing the "interface" + more
Class B: public A
{
public:
int foo();
int bar();
}
int main()
{
function(A); // Some magic function that would utlize the bar() method
return 0;
}
c++ oop inheritance interface solid-principles
add a comment |
This is very likely a silly question, but I can't seem to figure out if this is at all possible and if it should actually be done.
Say some code relies a lot on using a certain virtual base class acting as an interface and then deriving several subclasses that implements the virtual methods the base class. Is it possible to use functionality not exsisting in the base class (interface) below without completely disregarding the solid principles, when the rest of the program must not see anything but the base class "interface"? Like in the example below, is it possible to use bar() from the B class inside the function that only knows of A? And should I just add bar() to the "interface" instead?
// Base class - "interface"
Class A
{
public:
virtual int foo();
}
// Derived class - implementing the "interface" + more
Class B: public A
{
public:
int foo();
int bar();
}
int main()
{
function(A); // Some magic function that would utlize the bar() method
return 0;
}
c++ oop inheritance interface solid-principles
How could it call thebar
member function on anA
? Could you just makefunction
take aB
, and then just usedynamic_cast
?
– Artyer
Jan 1 at 23:25
This is what private virtual functions are for.A
can call its virtual function, that's implemented inB
, and the private function is not accessible from outside the class.
– Sam Varshavchik
Jan 1 at 23:27
This should do the trick:int B::foo() { bar(); }
– Eljay
Jan 1 at 23:37
add a comment |
This is very likely a silly question, but I can't seem to figure out if this is at all possible and if it should actually be done.
Say some code relies a lot on using a certain virtual base class acting as an interface and then deriving several subclasses that implements the virtual methods the base class. Is it possible to use functionality not exsisting in the base class (interface) below without completely disregarding the solid principles, when the rest of the program must not see anything but the base class "interface"? Like in the example below, is it possible to use bar() from the B class inside the function that only knows of A? And should I just add bar() to the "interface" instead?
// Base class - "interface"
Class A
{
public:
virtual int foo();
}
// Derived class - implementing the "interface" + more
Class B: public A
{
public:
int foo();
int bar();
}
int main()
{
function(A); // Some magic function that would utlize the bar() method
return 0;
}
c++ oop inheritance interface solid-principles
This is very likely a silly question, but I can't seem to figure out if this is at all possible and if it should actually be done.
Say some code relies a lot on using a certain virtual base class acting as an interface and then deriving several subclasses that implements the virtual methods the base class. Is it possible to use functionality not exsisting in the base class (interface) below without completely disregarding the solid principles, when the rest of the program must not see anything but the base class "interface"? Like in the example below, is it possible to use bar() from the B class inside the function that only knows of A? And should I just add bar() to the "interface" instead?
// Base class - "interface"
Class A
{
public:
virtual int foo();
}
// Derived class - implementing the "interface" + more
Class B: public A
{
public:
int foo();
int bar();
}
int main()
{
function(A); // Some magic function that would utlize the bar() method
return 0;
}
c++ oop inheritance interface solid-principles
c++ oop inheritance interface solid-principles
asked Jan 1 at 23:23
BertrampBertramp
96
96
How could it call thebar
member function on anA
? Could you just makefunction
take aB
, and then just usedynamic_cast
?
– Artyer
Jan 1 at 23:25
This is what private virtual functions are for.A
can call its virtual function, that's implemented inB
, and the private function is not accessible from outside the class.
– Sam Varshavchik
Jan 1 at 23:27
This should do the trick:int B::foo() { bar(); }
– Eljay
Jan 1 at 23:37
add a comment |
How could it call thebar
member function on anA
? Could you just makefunction
take aB
, and then just usedynamic_cast
?
– Artyer
Jan 1 at 23:25
This is what private virtual functions are for.A
can call its virtual function, that's implemented inB
, and the private function is not accessible from outside the class.
– Sam Varshavchik
Jan 1 at 23:27
This should do the trick:int B::foo() { bar(); }
– Eljay
Jan 1 at 23:37
How could it call the
bar
member function on an A
? Could you just make function
take a B
, and then just use dynamic_cast
?– Artyer
Jan 1 at 23:25
How could it call the
bar
member function on an A
? Could you just make function
take a B
, and then just use dynamic_cast
?– Artyer
Jan 1 at 23:25
This is what private virtual functions are for.
A
can call its virtual function, that's implemented in B
, and the private function is not accessible from outside the class.– Sam Varshavchik
Jan 1 at 23:27
This is what private virtual functions are for.
A
can call its virtual function, that's implemented in B
, and the private function is not accessible from outside the class.– Sam Varshavchik
Jan 1 at 23:27
This should do the trick:
int B::foo() { bar(); }
– Eljay
Jan 1 at 23:37
This should do the trick:
int B::foo() { bar(); }
– Eljay
Jan 1 at 23:37
add a comment |
1 Answer
1
active
oldest
votes
The short answer is yes, use the dynamic_cast
operator (but see below). The magic function would look something like this:
void function(A& a)
{
B* b = dynamic_cast<B*>(&a);
if (b)
{
// Object is a B...
b->bar();
}
else
{
// fallback logic using only methods on A
}
}
But be aware that many programmers consider this a code smell. In particular, if there's no way to implement the "fallback" branch, then it suggests the function should really accept a B
and something in the design may be amiss. (It's hard to say when talking in such generalities, however.) Also be aware that dynamic_cast
can be expensive, particularly with complex class hierarchies.
If at all reasonable, it's preferable to move the B
-specific logic into the B
class somehow. You might also consider making the bar
method a member of the A
class (A
would provide some sensible default implementation). Another approach might be to create a new interface to hold the bar
method and have your function accept an object of that type. (The B
class would implement both A
and the new interface.)
But if you have class C deriving B, dynamic_cast will pass for C too, but C may or may not implements bar() - how you will protect from someone passing C to function() and getting the default behavior? He will end with bar() again declared as virtual or final - to forbid the derived classes from implementing bar() by mistake and making it for "B only". The best design is to have such functions defined in base class too with clear default behavior.
– Baj Mile
Jan 2 at 1:45
As long as we follow the Liskov Substitution Principle, then passing aC
to the function (whereC
derives fromB
) will work fine.C
is aB
.
– Peter Ruderman
Jan 2 at 12:30
I agree that creating a new interface would be good in this case. I'm looking at a base class with 20 ish functions not counting operators and lifecycle methods though, and I'm seriously considering adding another just to maybe avoid refactoring the whole damned system. Doing as in your code example invites to breaking the open closed principle though imo
– Bertramp
Jan 2 at 22:13
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%2f53999717%2fhow-to-use-functions-from-derived-class-without-adding-them-to-the-base-class%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
The short answer is yes, use the dynamic_cast
operator (but see below). The magic function would look something like this:
void function(A& a)
{
B* b = dynamic_cast<B*>(&a);
if (b)
{
// Object is a B...
b->bar();
}
else
{
// fallback logic using only methods on A
}
}
But be aware that many programmers consider this a code smell. In particular, if there's no way to implement the "fallback" branch, then it suggests the function should really accept a B
and something in the design may be amiss. (It's hard to say when talking in such generalities, however.) Also be aware that dynamic_cast
can be expensive, particularly with complex class hierarchies.
If at all reasonable, it's preferable to move the B
-specific logic into the B
class somehow. You might also consider making the bar
method a member of the A
class (A
would provide some sensible default implementation). Another approach might be to create a new interface to hold the bar
method and have your function accept an object of that type. (The B
class would implement both A
and the new interface.)
But if you have class C deriving B, dynamic_cast will pass for C too, but C may or may not implements bar() - how you will protect from someone passing C to function() and getting the default behavior? He will end with bar() again declared as virtual or final - to forbid the derived classes from implementing bar() by mistake and making it for "B only". The best design is to have such functions defined in base class too with clear default behavior.
– Baj Mile
Jan 2 at 1:45
As long as we follow the Liskov Substitution Principle, then passing aC
to the function (whereC
derives fromB
) will work fine.C
is aB
.
– Peter Ruderman
Jan 2 at 12:30
I agree that creating a new interface would be good in this case. I'm looking at a base class with 20 ish functions not counting operators and lifecycle methods though, and I'm seriously considering adding another just to maybe avoid refactoring the whole damned system. Doing as in your code example invites to breaking the open closed principle though imo
– Bertramp
Jan 2 at 22:13
add a comment |
The short answer is yes, use the dynamic_cast
operator (but see below). The magic function would look something like this:
void function(A& a)
{
B* b = dynamic_cast<B*>(&a);
if (b)
{
// Object is a B...
b->bar();
}
else
{
// fallback logic using only methods on A
}
}
But be aware that many programmers consider this a code smell. In particular, if there's no way to implement the "fallback" branch, then it suggests the function should really accept a B
and something in the design may be amiss. (It's hard to say when talking in such generalities, however.) Also be aware that dynamic_cast
can be expensive, particularly with complex class hierarchies.
If at all reasonable, it's preferable to move the B
-specific logic into the B
class somehow. You might also consider making the bar
method a member of the A
class (A
would provide some sensible default implementation). Another approach might be to create a new interface to hold the bar
method and have your function accept an object of that type. (The B
class would implement both A
and the new interface.)
But if you have class C deriving B, dynamic_cast will pass for C too, but C may or may not implements bar() - how you will protect from someone passing C to function() and getting the default behavior? He will end with bar() again declared as virtual or final - to forbid the derived classes from implementing bar() by mistake and making it for "B only". The best design is to have such functions defined in base class too with clear default behavior.
– Baj Mile
Jan 2 at 1:45
As long as we follow the Liskov Substitution Principle, then passing aC
to the function (whereC
derives fromB
) will work fine.C
is aB
.
– Peter Ruderman
Jan 2 at 12:30
I agree that creating a new interface would be good in this case. I'm looking at a base class with 20 ish functions not counting operators and lifecycle methods though, and I'm seriously considering adding another just to maybe avoid refactoring the whole damned system. Doing as in your code example invites to breaking the open closed principle though imo
– Bertramp
Jan 2 at 22:13
add a comment |
The short answer is yes, use the dynamic_cast
operator (but see below). The magic function would look something like this:
void function(A& a)
{
B* b = dynamic_cast<B*>(&a);
if (b)
{
// Object is a B...
b->bar();
}
else
{
// fallback logic using only methods on A
}
}
But be aware that many programmers consider this a code smell. In particular, if there's no way to implement the "fallback" branch, then it suggests the function should really accept a B
and something in the design may be amiss. (It's hard to say when talking in such generalities, however.) Also be aware that dynamic_cast
can be expensive, particularly with complex class hierarchies.
If at all reasonable, it's preferable to move the B
-specific logic into the B
class somehow. You might also consider making the bar
method a member of the A
class (A
would provide some sensible default implementation). Another approach might be to create a new interface to hold the bar
method and have your function accept an object of that type. (The B
class would implement both A
and the new interface.)
The short answer is yes, use the dynamic_cast
operator (but see below). The magic function would look something like this:
void function(A& a)
{
B* b = dynamic_cast<B*>(&a);
if (b)
{
// Object is a B...
b->bar();
}
else
{
// fallback logic using only methods on A
}
}
But be aware that many programmers consider this a code smell. In particular, if there's no way to implement the "fallback" branch, then it suggests the function should really accept a B
and something in the design may be amiss. (It's hard to say when talking in such generalities, however.) Also be aware that dynamic_cast
can be expensive, particularly with complex class hierarchies.
If at all reasonable, it's preferable to move the B
-specific logic into the B
class somehow. You might also consider making the bar
method a member of the A
class (A
would provide some sensible default implementation). Another approach might be to create a new interface to hold the bar
method and have your function accept an object of that type. (The B
class would implement both A
and the new interface.)
answered Jan 2 at 1:06
Peter RudermanPeter Ruderman
10.2k2352
10.2k2352
But if you have class C deriving B, dynamic_cast will pass for C too, but C may or may not implements bar() - how you will protect from someone passing C to function() and getting the default behavior? He will end with bar() again declared as virtual or final - to forbid the derived classes from implementing bar() by mistake and making it for "B only". The best design is to have such functions defined in base class too with clear default behavior.
– Baj Mile
Jan 2 at 1:45
As long as we follow the Liskov Substitution Principle, then passing aC
to the function (whereC
derives fromB
) will work fine.C
is aB
.
– Peter Ruderman
Jan 2 at 12:30
I agree that creating a new interface would be good in this case. I'm looking at a base class with 20 ish functions not counting operators and lifecycle methods though, and I'm seriously considering adding another just to maybe avoid refactoring the whole damned system. Doing as in your code example invites to breaking the open closed principle though imo
– Bertramp
Jan 2 at 22:13
add a comment |
But if you have class C deriving B, dynamic_cast will pass for C too, but C may or may not implements bar() - how you will protect from someone passing C to function() and getting the default behavior? He will end with bar() again declared as virtual or final - to forbid the derived classes from implementing bar() by mistake and making it for "B only". The best design is to have such functions defined in base class too with clear default behavior.
– Baj Mile
Jan 2 at 1:45
As long as we follow the Liskov Substitution Principle, then passing aC
to the function (whereC
derives fromB
) will work fine.C
is aB
.
– Peter Ruderman
Jan 2 at 12:30
I agree that creating a new interface would be good in this case. I'm looking at a base class with 20 ish functions not counting operators and lifecycle methods though, and I'm seriously considering adding another just to maybe avoid refactoring the whole damned system. Doing as in your code example invites to breaking the open closed principle though imo
– Bertramp
Jan 2 at 22:13
But if you have class C deriving B, dynamic_cast will pass for C too, but C may or may not implements bar() - how you will protect from someone passing C to function() and getting the default behavior? He will end with bar() again declared as virtual or final - to forbid the derived classes from implementing bar() by mistake and making it for "B only". The best design is to have such functions defined in base class too with clear default behavior.
– Baj Mile
Jan 2 at 1:45
But if you have class C deriving B, dynamic_cast will pass for C too, but C may or may not implements bar() - how you will protect from someone passing C to function() and getting the default behavior? He will end with bar() again declared as virtual or final - to forbid the derived classes from implementing bar() by mistake and making it for "B only". The best design is to have such functions defined in base class too with clear default behavior.
– Baj Mile
Jan 2 at 1:45
As long as we follow the Liskov Substitution Principle, then passing a
C
to the function (where C
derives from B
) will work fine. C
is a B
.– Peter Ruderman
Jan 2 at 12:30
As long as we follow the Liskov Substitution Principle, then passing a
C
to the function (where C
derives from B
) will work fine. C
is a B
.– Peter Ruderman
Jan 2 at 12:30
I agree that creating a new interface would be good in this case. I'm looking at a base class with 20 ish functions not counting operators and lifecycle methods though, and I'm seriously considering adding another just to maybe avoid refactoring the whole damned system. Doing as in your code example invites to breaking the open closed principle though imo
– Bertramp
Jan 2 at 22:13
I agree that creating a new interface would be good in this case. I'm looking at a base class with 20 ish functions not counting operators and lifecycle methods though, and I'm seriously considering adding another just to maybe avoid refactoring the whole damned system. Doing as in your code example invites to breaking the open closed principle though imo
– Bertramp
Jan 2 at 22:13
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%2f53999717%2fhow-to-use-functions-from-derived-class-without-adding-them-to-the-base-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
How could it call the
bar
member function on anA
? Could you just makefunction
take aB
, and then just usedynamic_cast
?– Artyer
Jan 1 at 23:25
This is what private virtual functions are for.
A
can call its virtual function, that's implemented inB
, and the private function is not accessible from outside the class.– Sam Varshavchik
Jan 1 at 23:27
This should do the trick:
int B::foo() { bar(); }
– Eljay
Jan 1 at 23:37