Override virtual function with existing function - c++

Let me first say this is a purely academic question, since what I want to do can be better accomplished with multiple layers of inheritance.
That said, I wonder if it's possible to override a virtual function with an existing function without writing a wrapper or adding any inheritance layers. Code:
int myfunc2() { return 2; }
class Parent {
public:
virtual int myfunc() { return 0; }
};
class Child1 : public Parent {
public:
int myfunc() override { return 1; }
};
class Child2 : public Parent {
public:
// There a way to do this?
// int myfunc() = myfunc2;
// instead of this?
int myfunc() { return myfunc2(); };
};
int main() {
Child2 baz;
return baz.myfunc();
}
I'd like to override myfunc in the definition of Child2 by simply "forwarding" the declaration to the existing declaration of myfunc2.
Is this, or something akin to it, possible?
Context: I've got a bunch of child classes, some of which have identical definitions of myfunc, some of which do not. A better solution is to create an intermediate child class that defines the common myfunc and have the pertinent children inherit from that instead.

// There a way to do this?
// int myfunc() = myfunc2;
// instead of this?
int myfunc() { return myfunc2(); };
No, there isn't.

There is a problem.
A non-static member function accepts one more implicit parameter: pointer to the object itself. While a stand-alone function does not have such a parameter, For example you may not use the keyword this or member access syntax inside the definition of a stand alone function.

Related

Override virtual method with static method

Is there any specific reason why I cannot override virtual method from base class with static one?
Anyone knows why it would be bad idea?
Example:
#include <cstdio>
class Foo
{
public:
virtual void SomeMethod() = 0;
};
class Bar : public Foo
{
public:
static void SomeMethod() override
{
printf("SomeMethod");
}
};
void SomeFunctionWithFoo( Foo *p )
{
p->SomeMethod();
}
int main()
{
Bar o;
o.SomeMethod();
SomeFunctionWithFoo( &o );
Bar::SomeMethod();
o.StaticSomeMethod();
}
Instead I have to do this:
#include <cstdio>
class Foo
{
public:
virtual void SomeMethod() = 0;
};
class Bar : public Foo
{
public:
void SomeMethod() override
{
StaticSomeMethod();
}
static void StaticSomeMethod()
{
printf("SomeMethod");
}
};
void SomeFunctionWithFoo( Foo *p )
{
p->SomeMethod();
}
int main()
{
Bar o;
o.SomeMethod();
SomeFunctionWithFoo( &o );
Bar::StaticSomeMethod();
o.StaticSomeMethod();
}
I think as long as you don't need to access member variables, your function can be static, so that it can serve behaviour without object. In the same time such static function can serve behaviour when using interface. But maybe I am wrong and I am missing something?
With one method and two classes, it is not problem, but I have case of 10 such methods inside class, and many classes that inherit.
In real world scenario, such possibility would make my code simpler.
Summary: member functions have an invisible first parameter that your static method doesn't have.
Details: Member functions (effectively) are effectively all static methods that have an "invisible" first parameter, which is the Bar* this parameter, which tells the method which instance of the class to use. So the signature of virtual void SomeMethod() is, under the covers, actually static void SomeMethod(Foo*), but static StaticSomeMethod() doesn't have the same number of parameters.
C++ is mostly able to pretend this parameter doesn't exist, but overrides are one case where it pops up. You also see it occur when trying to bind a member function to a std::function, where you have to explicitly pass the this as the first pointer.

Namespace Functions within Class alternatives?

I'd like to be able to group similar functions in a class into a group so I don't need to append each name with what it's about.
I've seen this question which says that you can't have namespaces within classes. I've also seen this question which proposes using strongly typed enums. The problem here though, is that I'm not sure whether or not these enums can actually accomodate functions?
The problem contextualised:
class Semaphore
{
public:
void Set(bool State){Semaphore = State;}
bool Get(){return Semaphore;}
void Wait()
{
while (Semaphore)
{
//Wait until the node becomes available.
}
return;
}
private:
bool Semaphore = 0; //Don't operate on the same target simultaneously.
};
class Node : Semaphore
{
public:
unsigned long IP = 0; //IP should be stored in network order.
bool IsNeighbour = 0; //Single hop.
std::vector<int> OpenPorts;
//Rest of code...
};
Currently, NodeClass.Get() is how I can get the semaphore. However this introduces confusion as to what Get() actually gets. I'd like to have something akin to NodeClass.Semaphore::Get(). Otherwise I'd have to have the functions as SemaphoreSet(), SemaphoreGet(), and SemaphoreWait(), which isn't too well organised or nice looking.
I had thought of just having the Semaphore class on it's own, and instantiating it within the other classes, but if I could stick with the inheritance approach, that would be nicer.
So essentially, is it possible to access inherited methods like InheritedClass.Group::Function()?
If you really want to do this, you could force the user to call with the base class name by deleteing the member function in the subclass:
class Base {
public:
void Set(bool) { }
};
class Derived : public Base {
public:
void Set(bool) = delete;
};
int main() {
Derived d;
// d.Set(true); // compiler error
d.Base::Set(true);
}
However, if the semantics of calling Set on the subclass are significantly different than what you'd expect them to be when calling Set on the base class, you should probably use a data member and name a member function accordingly as you've described:
class Base {
public:
void Set(bool) { }
};
class Derived {
public:
void SetBase(bool b) {
b_.Set(b);
}
private:
Base b_;
};
int main() {
Derived d;
d.SetBase(true);
}

using directive and abstract method

I have a class (let's call it A) the inherits an interface defining several abstract methods and another class there to factor in some code (let's call it B).
The question is, I have an abstract method in the interface that A implements just to call the B version. Is there a way to use the keyword using to avoid writing a dull method like:
int A::method() override
{
return B::method();
}
I tried writing in A using B::method, but I still get an error that A doesn't implement the abstract method from the interface.
Is there a special technique to use in the case or am I just out of luck? (and if so, is there a specific reason why it should be that way?).
Thanks.
edit:
To clarify, the question is, why isn't it possible to just do this:
class A: public Interface, public B {
using B::method;
};
Let's make this clear. You basically have the following problem, right?
struct Interface
{
virtual void method() = 0;
};
struct B
{
void method()
{
// implementation of Interface::method
}
};
struct A : Interface, B
{
// some magic here to automatically
// override Interface::method and
// call B::method
};
This is simply impossible, because the fact that the methods have the same names is irrelevant from a technical point view. In other word's, Interface::method and B::method are simply not related to each other, and their identical names are not more than a coincidence, just like someone else called "Julien" doesn't have anything to do with you just because you share the same first name.
You are basically left with the following options:
1.) Just write the call manually:
struct A : Interface, B
{
virtual void method()
{
B::method();
}
};
2.) Minimise writing work with a macro, so that you can write:
struct A : Interface, B
{
OVERRIDE(method)
};
But I would strongly recommend against this solution. Less writing work for you = more reading work for everyone else.
3.) Change the class hierarchy, so that B implements Interface:
struct Interface
{
virtual void method() = 0;
};
struct B : Interface
{
virtual void method()
{
// implementation of Interface::method
}
};
struct A : B
{
};
if B::method is abstract you cannot call it because is not implemented... has no code.
An example:
class A
{
public:
virtual void method1( ) = 0;
virtual void method2( ){ }
};
class B : public A
{
public:
virtual void method1( ) override
{ return A::method1( ); } // Error. A::method1 is abstract
virtual method2( ) override
{ return A::method2( ); } // OK. A::method2 is an implemented method
}
Even if there were a way to do what you want, in the name of the readability of your code, I would not recommend that.
If you do not put the "B::" before "method" call, when I read that, I would say it is a recursive call.

c++ overriding a function only for a specific instance

I was wondering whether there's a way to override a function for a specific instance only. For ex,
class A
{
public:
...
void update();
...
}
int main()
{
...
A *first_instance = new A();
// I want this to have a specific update() function.
// ex. void update() { functionA(); functionB(); ... }
A *second_instance = new A();
// I want this to have a different update() function than the above one.
// ex. void update() { functionZ(); functionY(); ...}
A *third_instance = new A();
// ....so on.
...
}
Is there a way to achieve this?
I think virtual function is just what you want, with virtual function, different instances of the same type can have different functions, but you need to inherit the base class. for example
class A
{
public:
...
virtual void update()
{
std::cout << "Class A\n";
}
...
};
class B: public A
{
public:
virtual void update()
{
std::cout << "Class B\n";
}
};
class C: public A
{
public:
virtual void update()
{
std::cout << "Class C\n";
}
};
int main()
{
...
A *first_instance = new A();
// I want this to have a specific update() function.
// ex. void update() { functionA(); functionB(); ... }
A *second_instance = new B();
// I want this to have a different update() function than the above one.
// ex. void update() { functionZ(); functionY(); ...}
A *third_instance = new C();
// ....so on.
...
}
each instance in the above code will bind different update functions.
Besides, you can also use function pointer to implement your requirement, but it is not recommended. For example
class A
{
public:
A(void(*u)())
{
this->update = u;
}
...
void (*update)();
};
void a_update()
{
std::cout << "update A\n";
}
void b_update()
{
std::cout << "update B\n";
}
void c_update()
{
std::cout << "update C\n";
}
int main()
{
...
A first_instance(a_update);
// I want this to have a specific update() function.
// ex. void update() { functionA(); functionB(); ... }
A second_instance(b_update);
// I want this to have a different update() function than the above one.
// ex. void update() { functionZ(); functionY(); ...}
A third_instance(c_update);
// ....so on.
...
}
Hope helps!
Hold a function in the class.
#include <iostream>
#include <functional>
using namespace std;
class Foo
{
public:
Foo(const function<void ()>& f) : func(f)
{
}
void callFunc()
{
func();
}
private:
function<void ()> func;
};
void printFoo() { cout<<"foo"<<endl; }
void printBar() { cout<<"bar"<<endl; }
int main()
{
Foo a(printFoo);
Foo b(printBar);
a.callFunc();
b.callFunc();
}
You may have noticed that the end brace of a class is often followed by a semicolon, whereas the end braces of functions, while loops etc don't. There's a reason for this, which relates to a feature of struct in C. Because a class is almost identical to a struct, this feature exists for C++ classes too.
Basically, a struct in C may declare a named instance instead of (or as well as) a named "type" (scare quotes because a struct type in C isn't a valid type name in itself). A C++ class can therefore do the same thing, though AFAIK there may be severe limitations on what else that class can do.
I'm not in a position to check at the moment, and it's certainly not something I remember using, but that may mean you can declare a named class instance inheriting from a base class without giving it a class name. There will still be a derived type, but it will be anonymous.
If valid at all, it should look something like...
class : public baseclass // note - no derived class name
{
public:
virtual funcname ()
{
...
}
} instancename;
Personally, even if this is valid, I'd avoid using it for a number of reasons. For example, the lack of a class name means that it's not possible to define member functions separately. That means that the whole class declaration and definition must go where you want the instance declared - a lot of clutter to drop in the middle of a function, or even in a list of global variables.
With no class name, there's presumably no way to declare a constructor or destructor. And if you have non-default constructors from the base class, AFAIK there's no way to specify constructor parameters with this.
And as I said, I haven't checked this - that syntax may well be illegal as well as ugly.
Some more practical approaches to varying behaviour per-instance include...
Using dependency injection - e.g. providing a function pointer or class instance (or lambda) for some part of the behavior as a constructor parameter.
Using a template class - effectively compile-time dependency injection, with the dependency provided as a function parameter to the template.
I think it will be the best if you'll tell us why do you need to override a function for a specific instance.
But here's another approach: Strategy pattern.
Your class need a member that represent some behaviour. So you're creating some abstract class that will be an interface for different behaviours, then you'll implement different behaviours in subclasses of that abstract class. So you can choose those behaviours for any object at any time.
class A;//forward declaration
class Updater
{
public:
virtual ~Updater() {};//don't forget about virtual destructor, though it's not needed in this case of class containing only one function
virtual void update(A&) = 0;
}
class SomeUpdater
{
public:
virtual void update(A & a);//concrete realisation of an update() method
}
class A
{
private:
Updater mUpdater;
public:
explicit A(Updater updater);//constructor takes an updater, let's pretend we want to choose a behaviour once for a lifetime of an object - at creation
void update()
{
mUpdater.update(this);
}
}
You can use local classes, yet, personally, I consider the "hold function in the class" approach mentioned in the other answer better. I'd recommend the following approach only if doFunc must access internals of your base class, which is not possible from a function held in a member variable:
class ABase {
public:
void Func () { this->doFunc (); }
private:
virtual void doFunc () = 0;
public:
virtual ~ABase () { }
};
ABase* makeFirstA () {
class MyA : public ABase {
virtual void doFunc () { std::cout << "First A"; }
};
return new MyA;
}
ABase* makeSecondA () {
class MyA : public ABase {
virtual void doFunc () { std::cout << "Second A"; }
};
return new MyA;
}
int main () {
std::shared_ptr<ABase> first (makeFirstA ());
std::shared_ptr<ABase> second (makeSecondA ());
first->Func ();
second->Func ();
}
From a design patterns point of view, the "local classes" approach implements the template method pattern, while the "hold a function(al) in a member variable" approach reflects the strategy pattern. Which one is more appropriate depends on what you need to achieve.

Enforce static method overloading in child class in C++

I have something like this:
class Base
{
public:
static int Lolz()
{
return 0;
}
};
class Child : public Base
{
public:
int nothing;
};
template <typename T>
int Produce()
{
return T::Lolz();
}
and
Produce<Base>();
Produce<Child>();
both return 0, which is of course correct, but unwanted. Is there anyway to enforce the explicit declaration of the Lolz() method in the second class, or maybe throwing an compile-time error when using Produce<Child>()?
Or is it bad OO design and I should do something completely different?
EDIT:
What I am basically trying to do, is to make something like this work:
Manager manager;
manager.RegisterProducer(&Woot::Produce, "Woot");
manager.RegisterProducer(&Goop::Produce, "Goop");
Object obj = manager.Produce("Woot");
or, more generally, an external abstract factory that doesn't know the types of objects it is producing, so that new types can be added without writing more code.
There are two ways to avoid it. Actually, it depends on what you want to say.
(1) Making Produce() as an interface of Base class.
template <typename T>
int Produce()
{
return T::Lolz();
}
class Base
{
friend int Produce<Base>();
protected:
static int Lolz()
{
return 0;
}
};
class Child : public Base
{
public:
int nothing;
};
int main(void)
{
Produce<Base>(); // Ok.
Produce<Child>(); // error :'Base::Lolz' : cannot access protected member declared in class 'Base'
}
(2) Using template specialization.
template <typename T>
int Produce()
{
return T::Lolz();
}
class Base
{
public:
static int Lolz()
{
return 0;
}
};
class Child : public Base
{
public:
int nothing;
};
template<>
int Produce<Child>()
{
throw std::bad_exception("oops!");
return 0;
}
int main(void)
{
Produce<Base>(); // Ok.
Produce<Child>(); // it will throw an exception!
}
There is no way to override a static method in a subclass, you can only hide it. Nor is there anything analogous to an abstract method that would force a subclass to provide a definition. If you really need different behaviour in different subclasses, then you should make Lolz() an instance method and override it as normal.
I suspect that you are treading close to a design problem here. One of the principals of object-oriented design is the substitution principal. It basically says that if B is a subclass of A, then it must be valid to use a B wherever you could use an A.
C++ doesn't support virtual static functions. Think about what the vtable would have to look like to support that and you'll realize its a no-go.
or maybe throwing a compile-time error when using Produce<Child>()
The modern-day solution for this is to use delete:
class Child : public Base
{
public:
int nothing;
static int Lolz() = delete;
};
It helps avoid a lot of boilerplate and express your intentions clearly.
As far as I understand your question, you want to disable static method from the parent class. You can do something like this in the derived class:
class Child : public Base
{
public:
int nothing;
private:
using Base::Lolz;
};
Now Child::Lolz becomes private.
But, of course, it's much better to fix the design :)