Is it valid to “hide” a base class virtual function by making it pure virtual in derived classes?
Consider the example:
#include <iostream>
class A {
public:
virtual void f();
};
void A::f()
{
std::cout << "f() from An";
}
class B: public A {
public:
virtual void f() = 0;
};
class C: public B {
public:
void f();
};
void C::f()
{
std::cout << "f() from Cn";
}
int main()
{
C o;
o.f();
}
A::f() implementation is "hidden" from class C, which provides its own implementation for f() - effectively making A::f() more or less pointless. I see little value in such class hierarchy design, but my question whether this is a valid C++ or just "works" (such as undefined behaviours)?
c++ c++11 language-lawyer
add a comment |
Consider the example:
#include <iostream>
class A {
public:
virtual void f();
};
void A::f()
{
std::cout << "f() from An";
}
class B: public A {
public:
virtual void f() = 0;
};
class C: public B {
public:
void f();
};
void C::f()
{
std::cout << "f() from Cn";
}
int main()
{
C o;
o.f();
}
A::f() implementation is "hidden" from class C, which provides its own implementation for f() - effectively making A::f() more or less pointless. I see little value in such class hierarchy design, but my question whether this is a valid C++ or just "works" (such as undefined behaviours)?
c++ c++11 language-lawyer
Though it's "hidden" you can still useA::f()to callA's implementation (for example :o.A::f();).
– François Andrieux
37 mins ago
2
Consider usingoverridewhen overriding a base class'virtualmember function to avoid errors.
– François Andrieux
36 mins ago
@FrançoisAndrieux I understandA::f()can be called directly. I just wondered if this is a valid thing. Thanks for theoverridesuggestion which I often forget!
– usr
15 mins ago
add a comment |
Consider the example:
#include <iostream>
class A {
public:
virtual void f();
};
void A::f()
{
std::cout << "f() from An";
}
class B: public A {
public:
virtual void f() = 0;
};
class C: public B {
public:
void f();
};
void C::f()
{
std::cout << "f() from Cn";
}
int main()
{
C o;
o.f();
}
A::f() implementation is "hidden" from class C, which provides its own implementation for f() - effectively making A::f() more or less pointless. I see little value in such class hierarchy design, but my question whether this is a valid C++ or just "works" (such as undefined behaviours)?
c++ c++11 language-lawyer
Consider the example:
#include <iostream>
class A {
public:
virtual void f();
};
void A::f()
{
std::cout << "f() from An";
}
class B: public A {
public:
virtual void f() = 0;
};
class C: public B {
public:
void f();
};
void C::f()
{
std::cout << "f() from Cn";
}
int main()
{
C o;
o.f();
}
A::f() implementation is "hidden" from class C, which provides its own implementation for f() - effectively making A::f() more or less pointless. I see little value in such class hierarchy design, but my question whether this is a valid C++ or just "works" (such as undefined behaviours)?
c++ c++11 language-lawyer
c++ c++11 language-lawyer
asked 39 mins ago
usrusr
13.9k32139
13.9k32139
Though it's "hidden" you can still useA::f()to callA's implementation (for example :o.A::f();).
– François Andrieux
37 mins ago
2
Consider usingoverridewhen overriding a base class'virtualmember function to avoid errors.
– François Andrieux
36 mins ago
@FrançoisAndrieux I understandA::f()can be called directly. I just wondered if this is a valid thing. Thanks for theoverridesuggestion which I often forget!
– usr
15 mins ago
add a comment |
Though it's "hidden" you can still useA::f()to callA's implementation (for example :o.A::f();).
– François Andrieux
37 mins ago
2
Consider usingoverridewhen overriding a base class'virtualmember function to avoid errors.
– François Andrieux
36 mins ago
@FrançoisAndrieux I understandA::f()can be called directly. I just wondered if this is a valid thing. Thanks for theoverridesuggestion which I often forget!
– usr
15 mins ago
Though it's "hidden" you can still use
A::f() to call A's implementation (for example : o.A::f();).– François Andrieux
37 mins ago
Though it's "hidden" you can still use
A::f() to call A's implementation (for example : o.A::f();).– François Andrieux
37 mins ago
2
2
Consider using
override when overriding a base class' virtual member function to avoid errors.– François Andrieux
36 mins ago
Consider using
override when overriding a base class' virtual member function to avoid errors.– François Andrieux
36 mins ago
@FrançoisAndrieux I understand
A::f() can be called directly. I just wondered if this is a valid thing. Thanks for the override suggestion which I often forget!– usr
15 mins ago
@FrançoisAndrieux I understand
A::f() can be called directly. I just wondered if this is a valid thing. Thanks for the override suggestion which I often forget!– usr
15 mins ago
add a comment |
5 Answers
5
active
oldest
votes
It is clearly allowed and supported by the standard (cf, for example, this online C++ standard draft), and thus clearly not undefined behaviour:
10.4 Abstract classes
5 [ Note: An abstract class can be derived from a class that is not
abstract, and a pure virtual function may override a virtual function
which is not pure. — end note ]
The effect is that your class B becomes abstract and any subclass - if it shall not be abstract, too - must define f() then; the implementation in class A can still be invoked through A::f(), such that it is - from the perspective of reusing the implementation - not pointless.
add a comment |
my question whether this is a valid C++ or just "works" (such as undefined behaviours)?
The behaviour of the program is well defined.
effectively making
A::f()more or less pointless.
Of course, if you never call a function, then defining the function is unnecessary indeed. To clarify, the function would have to be declared pure virtual if you did choose to omit the definition (the opposite is not true; you can define a pure virtual function).
add a comment |
This will safely achieve the goal of requiring the author of C to provide an implementation for f().
I would query why this is needed — if the base implementation is not "valid" in your design then why does it exist, and/or why is it virtual?
They can still invoke A::f(), anyway, so whether this can be deemed "hiding" is open to debate.
It's unclear what the OP thinks is being hidden. Seems quite clear what it does and I don't see anything being hidden.
– doug
8 mins ago
I agree with your question - but a colleague argued this increases "safety" (i.e., it forces C to provide an implementation and avoids calling A::f() accidentally while allowing A::f() to be called directly if needed). bTW, the "hidden" is used for want of a better word. Hiding isn't really important to my question. Thanks.
– usr
7 mins ago
add a comment |
This is valid and well-defined C++.
It can occasionally be useful if you want to force a user of your class to implement a method that's already implemented in a base class (and don't want to use a different name which would be a more obvious choice). GUI libraries implementing operating system message pumps are one application.
add a comment |
As far as I can see there's no undefined behavior = 0 only means that derived classes must override it. But you can still provide an out-of-line definition for that function in the same class.
Remove "As far as I can see". Grow a pair!
– Bathsheba
12 secs ago
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%2f54330926%2fis-it-valid-to-hide-a-base-class-virtual-function-by-making-it-pure-virtual-in%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
5 Answers
5
active
oldest
votes
5 Answers
5
active
oldest
votes
active
oldest
votes
active
oldest
votes
It is clearly allowed and supported by the standard (cf, for example, this online C++ standard draft), and thus clearly not undefined behaviour:
10.4 Abstract classes
5 [ Note: An abstract class can be derived from a class that is not
abstract, and a pure virtual function may override a virtual function
which is not pure. — end note ]
The effect is that your class B becomes abstract and any subclass - if it shall not be abstract, too - must define f() then; the implementation in class A can still be invoked through A::f(), such that it is - from the perspective of reusing the implementation - not pointless.
add a comment |
It is clearly allowed and supported by the standard (cf, for example, this online C++ standard draft), and thus clearly not undefined behaviour:
10.4 Abstract classes
5 [ Note: An abstract class can be derived from a class that is not
abstract, and a pure virtual function may override a virtual function
which is not pure. — end note ]
The effect is that your class B becomes abstract and any subclass - if it shall not be abstract, too - must define f() then; the implementation in class A can still be invoked through A::f(), such that it is - from the perspective of reusing the implementation - not pointless.
add a comment |
It is clearly allowed and supported by the standard (cf, for example, this online C++ standard draft), and thus clearly not undefined behaviour:
10.4 Abstract classes
5 [ Note: An abstract class can be derived from a class that is not
abstract, and a pure virtual function may override a virtual function
which is not pure. — end note ]
The effect is that your class B becomes abstract and any subclass - if it shall not be abstract, too - must define f() then; the implementation in class A can still be invoked through A::f(), such that it is - from the perspective of reusing the implementation - not pointless.
It is clearly allowed and supported by the standard (cf, for example, this online C++ standard draft), and thus clearly not undefined behaviour:
10.4 Abstract classes
5 [ Note: An abstract class can be derived from a class that is not
abstract, and a pure virtual function may override a virtual function
which is not pure. — end note ]
The effect is that your class B becomes abstract and any subclass - if it shall not be abstract, too - must define f() then; the implementation in class A can still be invoked through A::f(), such that it is - from the perspective of reusing the implementation - not pointless.
answered 24 mins ago
Stephan LechnerStephan Lechner
27.6k22140
27.6k22140
add a comment |
add a comment |
my question whether this is a valid C++ or just "works" (such as undefined behaviours)?
The behaviour of the program is well defined.
effectively making
A::f()more or less pointless.
Of course, if you never call a function, then defining the function is unnecessary indeed. To clarify, the function would have to be declared pure virtual if you did choose to omit the definition (the opposite is not true; you can define a pure virtual function).
add a comment |
my question whether this is a valid C++ or just "works" (such as undefined behaviours)?
The behaviour of the program is well defined.
effectively making
A::f()more or less pointless.
Of course, if you never call a function, then defining the function is unnecessary indeed. To clarify, the function would have to be declared pure virtual if you did choose to omit the definition (the opposite is not true; you can define a pure virtual function).
add a comment |
my question whether this is a valid C++ or just "works" (such as undefined behaviours)?
The behaviour of the program is well defined.
effectively making
A::f()more or less pointless.
Of course, if you never call a function, then defining the function is unnecessary indeed. To clarify, the function would have to be declared pure virtual if you did choose to omit the definition (the opposite is not true; you can define a pure virtual function).
my question whether this is a valid C++ or just "works" (such as undefined behaviours)?
The behaviour of the program is well defined.
effectively making
A::f()more or less pointless.
Of course, if you never call a function, then defining the function is unnecessary indeed. To clarify, the function would have to be declared pure virtual if you did choose to omit the definition (the opposite is not true; you can define a pure virtual function).
edited 21 mins ago
answered 27 mins ago
eerorikaeerorika
79k556119
79k556119
add a comment |
add a comment |
This will safely achieve the goal of requiring the author of C to provide an implementation for f().
I would query why this is needed — if the base implementation is not "valid" in your design then why does it exist, and/or why is it virtual?
They can still invoke A::f(), anyway, so whether this can be deemed "hiding" is open to debate.
It's unclear what the OP thinks is being hidden. Seems quite clear what it does and I don't see anything being hidden.
– doug
8 mins ago
I agree with your question - but a colleague argued this increases "safety" (i.e., it forces C to provide an implementation and avoids calling A::f() accidentally while allowing A::f() to be called directly if needed). bTW, the "hidden" is used for want of a better word. Hiding isn't really important to my question. Thanks.
– usr
7 mins ago
add a comment |
This will safely achieve the goal of requiring the author of C to provide an implementation for f().
I would query why this is needed — if the base implementation is not "valid" in your design then why does it exist, and/or why is it virtual?
They can still invoke A::f(), anyway, so whether this can be deemed "hiding" is open to debate.
It's unclear what the OP thinks is being hidden. Seems quite clear what it does and I don't see anything being hidden.
– doug
8 mins ago
I agree with your question - but a colleague argued this increases "safety" (i.e., it forces C to provide an implementation and avoids calling A::f() accidentally while allowing A::f() to be called directly if needed). bTW, the "hidden" is used for want of a better word. Hiding isn't really important to my question. Thanks.
– usr
7 mins ago
add a comment |
This will safely achieve the goal of requiring the author of C to provide an implementation for f().
I would query why this is needed — if the base implementation is not "valid" in your design then why does it exist, and/or why is it virtual?
They can still invoke A::f(), anyway, so whether this can be deemed "hiding" is open to debate.
This will safely achieve the goal of requiring the author of C to provide an implementation for f().
I would query why this is needed — if the base implementation is not "valid" in your design then why does it exist, and/or why is it virtual?
They can still invoke A::f(), anyway, so whether this can be deemed "hiding" is open to debate.
answered 21 mins ago
Lightness Races in OrbitLightness Races in Orbit
287k51467792
287k51467792
It's unclear what the OP thinks is being hidden. Seems quite clear what it does and I don't see anything being hidden.
– doug
8 mins ago
I agree with your question - but a colleague argued this increases "safety" (i.e., it forces C to provide an implementation and avoids calling A::f() accidentally while allowing A::f() to be called directly if needed). bTW, the "hidden" is used for want of a better word. Hiding isn't really important to my question. Thanks.
– usr
7 mins ago
add a comment |
It's unclear what the OP thinks is being hidden. Seems quite clear what it does and I don't see anything being hidden.
– doug
8 mins ago
I agree with your question - but a colleague argued this increases "safety" (i.e., it forces C to provide an implementation and avoids calling A::f() accidentally while allowing A::f() to be called directly if needed). bTW, the "hidden" is used for want of a better word. Hiding isn't really important to my question. Thanks.
– usr
7 mins ago
It's unclear what the OP thinks is being hidden. Seems quite clear what it does and I don't see anything being hidden.
– doug
8 mins ago
It's unclear what the OP thinks is being hidden. Seems quite clear what it does and I don't see anything being hidden.
– doug
8 mins ago
I agree with your question - but a colleague argued this increases "safety" (i.e., it forces C to provide an implementation and avoids calling A::f() accidentally while allowing A::f() to be called directly if needed). bTW, the "hidden" is used for want of a better word. Hiding isn't really important to my question. Thanks.
– usr
7 mins ago
I agree with your question - but a colleague argued this increases "safety" (i.e., it forces C to provide an implementation and avoids calling A::f() accidentally while allowing A::f() to be called directly if needed). bTW, the "hidden" is used for want of a better word. Hiding isn't really important to my question. Thanks.
– usr
7 mins ago
add a comment |
This is valid and well-defined C++.
It can occasionally be useful if you want to force a user of your class to implement a method that's already implemented in a base class (and don't want to use a different name which would be a more obvious choice). GUI libraries implementing operating system message pumps are one application.
add a comment |
This is valid and well-defined C++.
It can occasionally be useful if you want to force a user of your class to implement a method that's already implemented in a base class (and don't want to use a different name which would be a more obvious choice). GUI libraries implementing operating system message pumps are one application.
add a comment |
This is valid and well-defined C++.
It can occasionally be useful if you want to force a user of your class to implement a method that's already implemented in a base class (and don't want to use a different name which would be a more obvious choice). GUI libraries implementing operating system message pumps are one application.
This is valid and well-defined C++.
It can occasionally be useful if you want to force a user of your class to implement a method that's already implemented in a base class (and don't want to use a different name which would be a more obvious choice). GUI libraries implementing operating system message pumps are one application.
answered 23 mins ago
BathshebaBathsheba
177k27253376
177k27253376
add a comment |
add a comment |
As far as I can see there's no undefined behavior = 0 only means that derived classes must override it. But you can still provide an out-of-line definition for that function in the same class.
Remove "As far as I can see". Grow a pair!
– Bathsheba
12 secs ago
add a comment |
As far as I can see there's no undefined behavior = 0 only means that derived classes must override it. But you can still provide an out-of-line definition for that function in the same class.
Remove "As far as I can see". Grow a pair!
– Bathsheba
12 secs ago
add a comment |
As far as I can see there's no undefined behavior = 0 only means that derived classes must override it. But you can still provide an out-of-line definition for that function in the same class.
As far as I can see there's no undefined behavior = 0 only means that derived classes must override it. But you can still provide an out-of-line definition for that function in the same class.
answered 20 mins ago
SebastianSebastian
111
111
Remove "As far as I can see". Grow a pair!
– Bathsheba
12 secs ago
add a comment |
Remove "As far as I can see". Grow a pair!
– Bathsheba
12 secs ago
Remove "As far as I can see". Grow a pair!
– Bathsheba
12 secs ago
Remove "As far as I can see". Grow a pair!
– Bathsheba
12 secs ago
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%2f54330926%2fis-it-valid-to-hide-a-base-class-virtual-function-by-making-it-pure-virtual-in%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
Though it's "hidden" you can still use
A::f()to callA's implementation (for example :o.A::f();).– François Andrieux
37 mins ago
2
Consider using
overridewhen overriding a base class'virtualmember function to avoid errors.– François Andrieux
36 mins ago
@FrançoisAndrieux I understand
A::f()can be called directly. I just wondered if this is a valid thing. Thanks for theoverridesuggestion which I often forget!– usr
15 mins ago