Compile time check of whether a method defined as virtual - c++

I'm trying to come up with a way of checking in the derived class whether a method of the base class is defines as 'virtual' . Basically I would like to have the following code:
class A {
virtual void vfoo() {}
void foo() {}
virtual ~A() {}
};
class B : public A {
virtual void vfoo() {
MAGIC_CHECK(m_pA->vfoo()); // succeed
// code
m_pA->vfoo();
// code
}
virtual void foo() {
MAGIC_CHECK(m_pA->foo()); // fail compilation because foo is not virtual!
// code
m_pA->foo();
// code
}
A * m_pA;
};
The question is, how do I implement this MAGIC_CHECK?
One solution for this could be using -Woverloaded-virtual compilation flag.
Can anyone suggest a solution that will not involve this flag?
Thanks!

In C++11 it's possible to add override at the end of the function declaration in the class and it will yield a warning if the function doesn't override anything:
class B : public A {
virtual void vfoo() override { //OK
}
virtual void foo() override { //error
}
};

In C++03 standard, it's not possible to check if a method is declared as virtual or not.
You may follow,
coding standards
peer review
possibly some static analysis tool

Related

Can modern compilers devirtualize function calls when using dependency injection

Dependency injection is a very important pattern when you want your code to be testable, and it is used all the time in big C++ projects.
Here is a simple example:
// Copyright 2019 Google LLC.
// SPDX-License-Identifier: Apache-2.0
class FooInterface {
public:
virtual void f() = 0;
virtual ~FooInterface() = default;
};
class Foo : public FooInterface {
public:
void f() override { /* Actual work */ }
};
class MockFoo : public FooInterface {
public:
void f() override { /* Mock code */ }
};
class Bar {
public:
Bar(std::unique_ptr<FooInterface>&& foo) : foo_(std::move(foo)) { }
void b() { foo_->f(); }
private:
std::unique_ptr<FooInterface> foo_;
};
// In production
void production() {
auto bar = std::make_unique<Bar>(std::make_unique<Foo>());
bar->b();
// ...
}
// In tests
void test() {
auto bar = std::make_unique<Bar>(std::make_unique<MockFoo>());
bar->b();
// ...
}
One doubt that I've always had is if compilers are able to devirtualize this kind of usage of virtual functions.
I know that in the general case it's impossible to know which derived class is being used, but in the example above the compiler knows which objects are being used in the production and the test functions, because they are being explicitly instantiated.
Can modern compilers optimize this special case and remove the virtual function calls given that they know which derived class is being instantiated at compile time?
If this specific example can't be devirtualized, is there any change that can be made to it so that the calls are devirtualized?
It depends on the compiler and the particular code you are dealing with. In my experience, you should not rely on it if you really care about avoiding virtual calls.
For instance, Clang/LLVM will devirtualize your example under -O2 if f() is noexcept:
class FooInterface {
public:
virtual void f() noexcept = 0;
virtual ~FooInterface() = default;
};
But other major compilers won't. Your mileage may vary.

static_assert : a certain function in Derive "must" hides Base's class function

I face a strange rare problem that I want to hide a Base class's function B::f1(int).
class B{
public: void f1(int){}
public: void f1(float){}
};
class C : public B{
public: void f1(int){
//static_assert(ASSERT_that_thisFunctionHidParentFunction,"");
//some rare ugly hacky stuff
}
public: void f1(char){
//static_assert(!ASSERT_that_thisFunctionHidParentFunction,"");
}
};
Everything works fine ; I just worry about maintainability.
I wish to make sure that a function C::f1(int) always hides B::f1(int).
If B::f1(int) happen to change signature in the future (e.g. to B::f1(int,int)),
I want some compile error to notify programmers that C::f1(int) should be changed to C::f1(int,int) as well.
In real world, my problematic function f1 doesn't have overload.
But for educational purpose, I wish to know how to solve it if there are overload too. (i.e. optional)
I love a cute solution like ASSERT_that_thisFunctionHidParentFunction in my code comment.
I don't mind MACRO.
My poor solution
I tried to typedef to force compile error, but it doesn't assert-fail in some case (MCVE-coliru), because int is automatically casted to B::f1(float).
class B{
public: void f1(int,int){}
public: void f1(float){}
};
class C : public B{
public: void f1(int){
using XXX=decltype(std::declval<B>().f1(std::declval<int>()));
//static_assert(ASSERT_that_thisFunctionHidParentFunction,"");
}
public: void f1(char){
//static_assert(!ASSERT_that_thisFunctionHidParentFunction,"");
}
};
int main() {
return 0;
}
You could check that the function pointers are different.
With MSVC 2019 and Clang 8 this worked for me, however GCC rejected it as "not a constant expression", so might need something different or a a runtime assert there. Not sure which is right in regards to the standard.
class B {
public:
void f1(int) {}
void f2(int) {}
void f3(int) {}
void f1(float) {}
};
class C : public B {
public:
void f1(int) {}
void f1(char) {}
void f3(int) {}
};
static_assert(&B::f1 != &C::f1); // Won't work because of the overloading, can static_cast to get the overload you want
static_assert(static_cast<void(B:: *)(int)>(&B::f1) != static_cast<void(C:: *)(int)>(&C::f1));
static_assert(static_cast<void(B:: *)(int)>(&B::f2) != static_cast<void(C:: *)(int)>(&C::f2)); // static assertion failed
static_assert(&B::f3 != &C::f3); // passes, no static_cast as not overloaded
Be very careful with hiding a member function in this way, as the base class is public and the method is not virtual. It can easily be cast and then the derived function is not called.
C *c = ...;
B *b = c; // Implicit
b->f1(5); // Calls B::f1, not C::f1
If possible it may be best to make the inheritance protected or private to avoid accidental casting.
The way I understand your question, it seems that you want to make sure that several implementation classes comply with a certain non-virtual concept.
template <typename Candidate>
struct ShipConcept
{
constexpr ShipConcept()
{
using ProtoFoo = void (Candidate::*)(int);
(void)static_cast<ProtoFoo>(&Candidate::foo);
// Other tests ...
}
};
struct Ship_A
: private ShipConcept<Ship_A>
{
Ship_A()
{
}
void foo(int, int);
void foo(float);
void foo(int); // (1)
};
You'll get compile-time error if line (1) isn't there.

Abstract class and inheritance

class MyInterface {
public:
virtual void someFunction()= 0;
};
class X: public MyInterface {
private:
virtual void doThis() {
printf("This X");
}
virtual void doThat() {
printf("That X");
}
public:
void someFunction() {
doThis();
doThat();
}
};
class Y: public MyInterface, private X {
private:
void doThat() {
printf("That Y");
}
};
MyInterface *iface= new Y();
Y->someFunction();
Coming from Java's flavor of OOP, I am trying to wrap my head around the OOP model of C++. I have read this: http://www.gotw.ca/publications/mill18.htm for suggestions how to design interfaces in C++. The above code is a direct application (or a slight variation thereof) of the rule the author expounds. My question is, is the code above going to produce "This X" followed by "That Y"? What I find confusing is that the author recommends using virtual in conjunction with private. My reasoning is, if a function is private, how are we to override it at all?
In the above code, it is granted that Y can be used as the right-hand-side of the assignment, since we derive publicly from the interface. When we call someFunction() on it, since we do not explicitly provide any implementation inside class Y, is it going to use the implementation from class X? Then, provided it does, it looks at doThat() and again uses Ys implementation of it?
The code has a few problems. Here is a working example:
class MyInterface
{
public:
virtual ~MyInterface() { }
virtual void someFunction() = 0;
};
class X : public MyInterface
{
private:
virtual void doThis()
{
printf("This X\n");
}
virtual void doThat()
{
printf("That X\n");
}
public:
void someFunction()
{
doThis();
doThat();
}
};
class Y : public X
{
private:
void doThat()
{
printf("That Y\n");
}
};
int main()
{
MyInterface *iface = new Y();
iface->someFunction();
delete iface;
}
Explanations
You need to use class Y : public X to be able to use the implementation of void X::someFunction()
Unfortunately there is no real interface in C++ and there is only a workaround using pure virtual class. This workaround with two parents has it's own limitations (see bellow). And therefore it is also a good idea to add a destructor to interface definition.
When you use class Y: public MyInterface, private X you need to provide a custom implementation of MyInterface::someFunction(). You have have two parent classes and someFunction() in both parents (X and MyInterface). This is necessary even when there is only one implementation of function. Therefore you need to specify which parent class 'implementation' will be used. Error:
'Y': cannot instantiate abstract class
You also get a error when you remove the interface (try to use the interface from X). The reason is simple, when X is private, the implementation is not public and can not be used as a interface.
'type cast': conversion from 'Y *' to 'MyInterface *' exists, but is inaccessible
You are using class as type in Y->someFunction();
I have no idea, why you can override a private virtual function. I mostly work in C# now and this 'feature' of C++ is something I do not get. You are right, that this should be bad code, but it work (at least in Visual Studio 2017).
I would also like to know, why this is not considered as error/incorrect code construction.

Derived Class Calling Non-Public Base Class Virtual Function

EDITED:
This question has already been asked here
but didn't help in my case. I'm trying to have a hierarchy of classes, with inherited public update() functions. But I want a given derived derived class to call the functionality of all of its base classes before doing its own processing. My actual VS2013 solution consists of an EXE project that references a DLL project, but the simplified code below still produces the error:
// Map.h (in DLL project)
namespace Game2D {
class Map {
public:
explicit Map();
~Map();
void update(double);
protected:
virtual void baseUpdates(double dt) {}
};
}
// Map.cpp (in DLL project)
namespace Game2D {
Map::Map() { }
Map::~Map() {}
void Map::update(double dt) {
baseUpdates(dt);
// Do some base stuf...
}
}
// AutoScrollMap.h (in DLL project)
namespace Game2D {
class AutoScrollMap : public Map {
public:
explicit AutoScrollMap();
~AutoScrollMap();
protected:
virtual void baseUpdates(double) {}
};
}
// AutoScrollMap.cpp (in DLL project)
namespace Game2D {
AutoScrollMap::AutoScrollMap() : Game2D::Map() {}
AutoScrollMap::~AutoScrollMap() {}
void AutoScrollMap::baseUpdates(double dt) {
// Do some stuff...
}
}
// DesertMap.h (in EXE project)
namespace Shooter {
class DesertMap : public Game2D::AutoScrollMap {
public:
explicit DesertMap();
~DesertMap();
protected:
virtual void baseUpdates(double);
};
}
// DesertMap.cpp (in EXE project)
namespace Shooter {
DesertMap::DesertMap() : Game2D::AutoScrollMap() {}
DesertMap::~DesertMap() {}
void DesertMap::baseUpdates(double dt) {
AutoScrollMap::baseUpdates(dt);
// Do more specific stuff...
}
}
This gives me a compiler error of "error C2084: function 'void Game2D::AutoScrollMap::baseUpdates(double)' already has a body". The article above says I can use this syntax to call a function that is being overloaded. However, the base function in its example was public, not protected, and I really want to keep baseUpdates() protected since its not part of the interface.
I thought this problem was a fairly basic use of the OOP inheritance paradigm, so what am I missing? All advice is greatly appreciated!
The method you described has no problem, the problem is in your code. You already implemented Derived2::baseUpdates() inline, then you try to define it again. You should change Derived2 to this:
class Derived2 : public Derived1 {
public:
Derived2() : Derived1() { }
protected:
virtual void baseUpdates();
};
void Derived2::baseUpdates() {
Derived1::baseUpdates();
}
Also your Base constructor is not implemented.
Wow, trying to reduce this code to its simplest form for help actually revealed the problem. I had already put braces "{}" after baseUpdates() in AutoScrollMap.h, hence the "function already has body" error. Looks like you sure can call base virtual functions from derived overrides, even if the base function is not public! Sorry for wasting everybody's time, haha.

Is it possible to recognize undesirable overriding of virtual functions? [duplicate]

This question already has answers here:
How to enforce the 'override' keyword?
(2 answers)
Ways to detect whether a C++ virtual function has been redefined in a derived class
(9 answers)
Closed 8 years ago.
For example:
struct A
{
virtual void go() { };
};
struct B : public A
{
void go() { };
};
Implicit overriding of function go can be undesirable, because it is not recognizable that B::go() is hiding or overriding the same function of struct A or even it may be a new function that does not exist in struct A. override feature of C++11 is useful when you want a desirable overriding of virtual functions, but in my case it is undesirable and i didn't want to override function go(), that means if i knew there was a virtual function I wouldn't override it in struct B.
What i want is something similar to [[check_names]] attribute proposal that didn't approve to C++11. Does C++ have a language feature for it?
By the way, do compilers (such as GCC and VC++) have an option to show a warning (a warning is enough if error is not available!) if an implicit overriding of a virtual function happens? if they have, can you provide an example for GCC?
EDIT: I am not talking about force or a language feature, all i want is a warning or anything that allow me to recognize the undesirable overriding.
EDIT: What can be a desirable overriding? it can be something like the following code:
struct A
{
virtual void go() { };
};
struct B : public A
{
virtual void go() { };
};
or:
struct A
{
virtual void go() { };
};
struct B : public A
{
void go() override { };
};
or something similar by using an attribute.
I guess you can use tagging,
#include <iostream>
#include <memory>
using namespace std;
struct no_override_tag
{};
struct A
{
virtual void go() { cout <<"A::go" << endl;};
};
struct B : public A
{
void go(no_override_tag={}) { cout << "B::go" <<endl; };
};
int main()
{
unique_ptr<A> upA(new B);
upA->go(); // no override, calls `A::go()` instead of `B::go()`
}
Basically you add a default-initialized argument of a type no_override_tag as the last argument in B::go(), and this will make the signature of B::go different, no matter what you declaration you have in A. Not super elegant but it works, however I don't know why would you really want to do this.