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

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.

Related

Optional class members without runtime overhead

I have the following very general problem that I have not found a satisfying solution to yet:
So I want to have two classes A and AData that are basically identical except that the latter has an additional attribute data and each of the classes supports a function foo(), which is different because it depends on the existence of the additional data.
The stupid solution is to copy the entire class and change it slightly, but that leads to code duplication and is hard to maintain. Using std::optional or a pointer lead to additional checks and therefore runtime overhead, right?
My question is whether there is a way to get the same runtime performance as just copying the code without actual code duplication? My current solution is to make AData a derived class and declare it as friend of A and then override the virtual function foo(), but I do not like this approach due to the use of friend.
You can use static polymorphism and curiosly recurring template pattern.
Both A and AData provide foo() but behaviour is class-specfic through doFoo(). Also not using virtual dispatch avoids runtime overhead of vtable lookup.
template <typename TData>
class Abase
{
public:
void foo()
{
static_cast<TData*>(this)->doFoo();
}
};
class A : public Abase<A>
{
friend ABase<A>;
void doFoo() { cout << "A::foo()\n"; }
};
class AData : public Abase<AData>
{
friend Abase<AData>;
int someDataMember;
void doFoo() { cout << "AData::foo()\n"; /*... use someDataMember ... */}
};
Live
Why not use composition:
class A
{
public:
void foo() { /*...*/ }
};
class AData
{
A a;
int someDataMember;
public:
void foo() { /*... use someDataMember ...*/ }
};

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.

C++: Test if class instance implements a virtual method [duplicate]

I want to be able to tell at run-time if an instance of a class implements a virtual function. For example:
struct Base
{
virtual void func(int x) { <default behavior here> }
virtual void func2(int x) { <default behavior here> }
};
struct Deriv : Base
{
virtual void func(int x) override { <new behavior here> }
};
int main()
{
Base *d = new Deriv;
if(implements<Base::func(int)>(d)) // This should evaluate true
{}
if(implements<Base::func2(int)>(d)) // This should evaluate false
{}
}
I have seen this but it's dated and there might be a something that c++11/14 has to say now:
Ways to detect whether a C++ virtual function has been redefined in a derived class
The short answer is: No. And certainly not in a portable manner.
The longer answer: actually, the very goal of polymorphism is to make it indistinguishable to the user where the functionality comes from.
Even if the developer does not write code, the compiler might still generate a dedicated version of the function for the derived class (for better optimization). This would throw off even non-portable implementations that would inspect the virtual tables...
An alternative route, however, would be to throw off C++ automatic run-time polymorphism and instead provide an ad-hoc implementation. If for example you were to provide your own virtual table/pointer mechanism, then you would have more control:
struct VirtualTable {
typedef void (*FuncType)(void*, int);
typedef void (*Func2Type)(void*, int);
FuncType func;
Func2Type func2;
};
and you could check whether the function pointer is, or is not, equal to the default.
What comes to my mind right now is to have a special "counter" variable, which will take its value based on the implementation and zero if the base-class function is called. I think that this sounds a bit obsolete style though and try to find a better solution in a moment. See the example for now:
struct Base
{
virtual void func(int x, int& implemented) {implemented = 0;}
};
struct Deriv : Base
{
virtual void func(int x, int& implemented) override {implemented = 1;}
};
If the functions are void as in your example, you also can use "return codes" - just return implemented value back.

why it is not possible to implement inherited pure virtual method with 'using' directive? [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Why does C++ not let baseclasses implement a derived class' inherited interface?
#include <iostream>
class Interface
{
public:
virtual void yell(void) = 0;
};
class Implementation
{
public:
void yell(void)
{
std::cout << "hello world!" << std::endl;
}
};
class Test: private Implementation, public Interface
{
public:
using Implementation::yell;
};
int main (void)
{
Test t;
t.yell();
}
I want the Test class to be implemented in terms of Implementation, and I want to avoid the need to write the
void Test::yell(void) { Implementation::yell(); }
method. Why it is not possible to do it this way? Is there any other way in C++03?
using only brings a name into a scope.
It doesn't implement anything.
If you want Java-like get-implementation-by-inheritance, then you have to explicitly add the overhead associated with that, namely virtual inheritance, like this:
#include <iostream>
class Interface
{
public:
virtual void yell() = 0;
};
class Implementation
: public virtual Interface
{
public:
void yell()
{
std::cout << "hello world!" << std::endl;
}
};
class Test: private Implementation, public virtual Interface
{
public:
using Implementation::yell;
};
int main ()
{
Test t;
t.yell();
}
EDIT: a bit sneaky this feature, I had to edit to make the code compile with g++. Which didn't automatically recognize that the implementation yell and the interface yell were one and the same. I'm not completely sure what the standard says about that!

Compile time check of whether a method defined as virtual

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