deleting or throwing compiler error when a virtual base function is called from a derived class in c++
I have the following code:
class A
{
public:
virtual void f(int a) = 0;
virtual void f(int a, int b) = 0;
};
class B : public A
{
public:
// do not want f(int a,int b) accessible
void f(int a);
};
class C : public A
{
public:
// do not want f(int a) accessible
void f(int a, int b);
};
I am aware that purely virtual functions cannot be deleted. Is there any way to disable these functions such that a compile time error occurs if an instance of B tries to call f(int,int) or when an instance of C tries to call f(int)
c++ oop c++11 polymorphism virtual-functions
add a comment |
I have the following code:
class A
{
public:
virtual void f(int a) = 0;
virtual void f(int a, int b) = 0;
};
class B : public A
{
public:
// do not want f(int a,int b) accessible
void f(int a);
};
class C : public A
{
public:
// do not want f(int a) accessible
void f(int a, int b);
};
I am aware that purely virtual functions cannot be deleted. Is there any way to disable these functions such that a compile time error occurs if an instance of B tries to call f(int,int) or when an instance of C tries to call f(int)
c++ oop c++11 polymorphism virtual-functions
Did you mean detecting instead of deleting (in the question title)?
– François Andrieux
Nov 23 '18 at 20:03
They are both pure virtual, so they would need to be implemented. that's the compilation error if you try to instantiate B or C.
– Matthieu Brucher
Nov 23 '18 at 20:04
1
What would happen if it is called fromA
interface (B b; A& a = b; a.f(4, 2);
)?
– Jarod42
Nov 23 '18 at 20:04
The nature ofvirtual
is that you can't necessarily know at compile time which function will actually be called at a given call site. Edit : Maybe what you want is to implement bothA::f(int)
andA::f(int, int)
so that they throw, terminate or whatever. That way trying to call it with an instance that doesn't provide it can be detected.
– François Andrieux
Nov 23 '18 at 20:05
3
This just seems wrong. Neither B nor C is really an A here. How about just splitting A into two distinct interfaces?
– StoryTeller
Nov 23 '18 at 20:07
add a comment |
I have the following code:
class A
{
public:
virtual void f(int a) = 0;
virtual void f(int a, int b) = 0;
};
class B : public A
{
public:
// do not want f(int a,int b) accessible
void f(int a);
};
class C : public A
{
public:
// do not want f(int a) accessible
void f(int a, int b);
};
I am aware that purely virtual functions cannot be deleted. Is there any way to disable these functions such that a compile time error occurs if an instance of B tries to call f(int,int) or when an instance of C tries to call f(int)
c++ oop c++11 polymorphism virtual-functions
I have the following code:
class A
{
public:
virtual void f(int a) = 0;
virtual void f(int a, int b) = 0;
};
class B : public A
{
public:
// do not want f(int a,int b) accessible
void f(int a);
};
class C : public A
{
public:
// do not want f(int a) accessible
void f(int a, int b);
};
I am aware that purely virtual functions cannot be deleted. Is there any way to disable these functions such that a compile time error occurs if an instance of B tries to call f(int,int) or when an instance of C tries to call f(int)
c++ oop c++11 polymorphism virtual-functions
c++ oop c++11 polymorphism virtual-functions
asked Nov 23 '18 at 20:02
basilbasil
3091722
3091722
Did you mean detecting instead of deleting (in the question title)?
– François Andrieux
Nov 23 '18 at 20:03
They are both pure virtual, so they would need to be implemented. that's the compilation error if you try to instantiate B or C.
– Matthieu Brucher
Nov 23 '18 at 20:04
1
What would happen if it is called fromA
interface (B b; A& a = b; a.f(4, 2);
)?
– Jarod42
Nov 23 '18 at 20:04
The nature ofvirtual
is that you can't necessarily know at compile time which function will actually be called at a given call site. Edit : Maybe what you want is to implement bothA::f(int)
andA::f(int, int)
so that they throw, terminate or whatever. That way trying to call it with an instance that doesn't provide it can be detected.
– François Andrieux
Nov 23 '18 at 20:05
3
This just seems wrong. Neither B nor C is really an A here. How about just splitting A into two distinct interfaces?
– StoryTeller
Nov 23 '18 at 20:07
add a comment |
Did you mean detecting instead of deleting (in the question title)?
– François Andrieux
Nov 23 '18 at 20:03
They are both pure virtual, so they would need to be implemented. that's the compilation error if you try to instantiate B or C.
– Matthieu Brucher
Nov 23 '18 at 20:04
1
What would happen if it is called fromA
interface (B b; A& a = b; a.f(4, 2);
)?
– Jarod42
Nov 23 '18 at 20:04
The nature ofvirtual
is that you can't necessarily know at compile time which function will actually be called at a given call site. Edit : Maybe what you want is to implement bothA::f(int)
andA::f(int, int)
so that they throw, terminate or whatever. That way trying to call it with an instance that doesn't provide it can be detected.
– François Andrieux
Nov 23 '18 at 20:05
3
This just seems wrong. Neither B nor C is really an A here. How about just splitting A into two distinct interfaces?
– StoryTeller
Nov 23 '18 at 20:07
Did you mean detecting instead of deleting (in the question title)?
– François Andrieux
Nov 23 '18 at 20:03
Did you mean detecting instead of deleting (in the question title)?
– François Andrieux
Nov 23 '18 at 20:03
They are both pure virtual, so they would need to be implemented. that's the compilation error if you try to instantiate B or C.
– Matthieu Brucher
Nov 23 '18 at 20:04
They are both pure virtual, so they would need to be implemented. that's the compilation error if you try to instantiate B or C.
– Matthieu Brucher
Nov 23 '18 at 20:04
1
1
What would happen if it is called from
A
interface (B b; A& a = b; a.f(4, 2);
)?– Jarod42
Nov 23 '18 at 20:04
What would happen if it is called from
A
interface (B b; A& a = b; a.f(4, 2);
)?– Jarod42
Nov 23 '18 at 20:04
The nature of
virtual
is that you can't necessarily know at compile time which function will actually be called at a given call site. Edit : Maybe what you want is to implement both A::f(int)
and A::f(int, int)
so that they throw, terminate or whatever. That way trying to call it with an instance that doesn't provide it can be detected.– François Andrieux
Nov 23 '18 at 20:05
The nature of
virtual
is that you can't necessarily know at compile time which function will actually be called at a given call site. Edit : Maybe what you want is to implement both A::f(int)
and A::f(int, int)
so that they throw, terminate or whatever. That way trying to call it with an instance that doesn't provide it can be detected.– François Andrieux
Nov 23 '18 at 20:05
3
3
This just seems wrong. Neither B nor C is really an A here. How about just splitting A into two distinct interfaces?
– StoryTeller
Nov 23 '18 at 20:07
This just seems wrong. Neither B nor C is really an A here. How about just splitting A into two distinct interfaces?
– StoryTeller
Nov 23 '18 at 20:07
add a comment |
2 Answers
2
active
oldest
votes
There's no way to do that. You'd need a more complex class hierarchy. Something like this:
class A
{
public:
virtual ~A() {}
};
class BaseForB : public A
{
public:
virtual void f(int a) = 0;
};
class BaseForC : public A
{
public:
virtual void f(int a, int b) = 0;
};
class B : public BaseForB
{
public:
void f(int a) override
{
// details...
}
};
class C : public BaseForC
{
public:
void f(int a, int b) override
{
// details...
}
};
add a comment |
One option is to put a class between A B and A which implements a private version of the function that is final and not callable by instances of B like this:
class A
{
public:
virtual void f(int a) = 0;
virtual void f(int a, int b) = 0;
};
class A_B : public A {
using A::f;
private:
void f(int a, int b) final override {}
};
class B : public A_B
{
public:
// do not want f(int a,int b) accessible
void f(int a);
};
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%2f53452375%2fdeleting-or-throwing-compiler-error-when-a-virtual-base-function-is-called-from%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
There's no way to do that. You'd need a more complex class hierarchy. Something like this:
class A
{
public:
virtual ~A() {}
};
class BaseForB : public A
{
public:
virtual void f(int a) = 0;
};
class BaseForC : public A
{
public:
virtual void f(int a, int b) = 0;
};
class B : public BaseForB
{
public:
void f(int a) override
{
// details...
}
};
class C : public BaseForC
{
public:
void f(int a, int b) override
{
// details...
}
};
add a comment |
There's no way to do that. You'd need a more complex class hierarchy. Something like this:
class A
{
public:
virtual ~A() {}
};
class BaseForB : public A
{
public:
virtual void f(int a) = 0;
};
class BaseForC : public A
{
public:
virtual void f(int a, int b) = 0;
};
class B : public BaseForB
{
public:
void f(int a) override
{
// details...
}
};
class C : public BaseForC
{
public:
void f(int a, int b) override
{
// details...
}
};
add a comment |
There's no way to do that. You'd need a more complex class hierarchy. Something like this:
class A
{
public:
virtual ~A() {}
};
class BaseForB : public A
{
public:
virtual void f(int a) = 0;
};
class BaseForC : public A
{
public:
virtual void f(int a, int b) = 0;
};
class B : public BaseForB
{
public:
void f(int a) override
{
// details...
}
};
class C : public BaseForC
{
public:
void f(int a, int b) override
{
// details...
}
};
There's no way to do that. You'd need a more complex class hierarchy. Something like this:
class A
{
public:
virtual ~A() {}
};
class BaseForB : public A
{
public:
virtual void f(int a) = 0;
};
class BaseForC : public A
{
public:
virtual void f(int a, int b) = 0;
};
class B : public BaseForB
{
public:
void f(int a) override
{
// details...
}
};
class C : public BaseForC
{
public:
void f(int a, int b) override
{
// details...
}
};
edited Nov 23 '18 at 20:22
answered Nov 23 '18 at 20:11
Peter RudermanPeter Ruderman
10.2k2352
10.2k2352
add a comment |
add a comment |
One option is to put a class between A B and A which implements a private version of the function that is final and not callable by instances of B like this:
class A
{
public:
virtual void f(int a) = 0;
virtual void f(int a, int b) = 0;
};
class A_B : public A {
using A::f;
private:
void f(int a, int b) final override {}
};
class B : public A_B
{
public:
// do not want f(int a,int b) accessible
void f(int a);
};
add a comment |
One option is to put a class between A B and A which implements a private version of the function that is final and not callable by instances of B like this:
class A
{
public:
virtual void f(int a) = 0;
virtual void f(int a, int b) = 0;
};
class A_B : public A {
using A::f;
private:
void f(int a, int b) final override {}
};
class B : public A_B
{
public:
// do not want f(int a,int b) accessible
void f(int a);
};
add a comment |
One option is to put a class between A B and A which implements a private version of the function that is final and not callable by instances of B like this:
class A
{
public:
virtual void f(int a) = 0;
virtual void f(int a, int b) = 0;
};
class A_B : public A {
using A::f;
private:
void f(int a, int b) final override {}
};
class B : public A_B
{
public:
// do not want f(int a,int b) accessible
void f(int a);
};
One option is to put a class between A B and A which implements a private version of the function that is final and not callable by instances of B like this:
class A
{
public:
virtual void f(int a) = 0;
virtual void f(int a, int b) = 0;
};
class A_B : public A {
using A::f;
private:
void f(int a, int b) final override {}
};
class B : public A_B
{
public:
// do not want f(int a,int b) accessible
void f(int a);
};
answered Nov 23 '18 at 20:41
Ian4264 Ian4264
13514
13514
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%2f53452375%2fdeleting-or-throwing-compiler-error-when-a-virtual-base-function-is-called-from%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
Did you mean detecting instead of deleting (in the question title)?
– François Andrieux
Nov 23 '18 at 20:03
They are both pure virtual, so they would need to be implemented. that's the compilation error if you try to instantiate B or C.
– Matthieu Brucher
Nov 23 '18 at 20:04
1
What would happen if it is called from
A
interface (B b; A& a = b; a.f(4, 2);
)?– Jarod42
Nov 23 '18 at 20:04
The nature of
virtual
is that you can't necessarily know at compile time which function will actually be called at a given call site. Edit : Maybe what you want is to implement bothA::f(int)
andA::f(int, int)
so that they throw, terminate or whatever. That way trying to call it with an instance that doesn't provide it can be detected.– François Andrieux
Nov 23 '18 at 20:05
3
This just seems wrong. Neither B nor C is really an A here. How about just splitting A into two distinct interfaces?
– StoryTeller
Nov 23 '18 at 20:07