Suppose I have an interface class and a partial implementation class. Also, suppose that I absolutely do not want this partial implementation to inherit from the interface:
class interface {
virtual void fnA() const = 0;
virtual void fnB() const = 0;
};
class partialImplementation { //Do not want to inherit from interface!
void fnA() const {cout << "fnA from partial implementation" << endl;}
//fnB() not implemented
};
The idea is that I'm planning to make several new classes all inheriting the interface, but I want to implement the same fnA() in each one. So, after inheriting the interface, maybe I could also inherit the partial implementation and hope that fnA() gets implemented. For example,
class myClass : interface, partialImplementation {
//would like fnA() to be implemented by partialImplementation
void fnB() const {cout << "fnB from myClass" << endl;}
};
Of course, if you try to instantiate this class, you get this error:
main.cpp: In function 'int main()':
main.cpp:235:10: error: cannot declare variable 'm' to be of abstract type 'myClass'
main.cpp:201:7: note: because the following virtual functions are pure within 'myClass':
main.cpp:193:15: note: virtual void interface::fnA() const
Compilation failed.
After reading some other stackoverflow posts (like this one) it seems the only available solution is to do this:
class myClass : interface, partialImplementation {
public:
void fnB() const {cout << "fnB from myClass" << endl;}
void fnA() const {
partialImplementation::fnA();
}
};
In the linked post, the OP didn't mind typing three extra lines. But you could imagine that I actually want partialImplementation to implement more than just one function, and that I could be typing this same boilerplate over and over every time I want to make a new class inheriting this interface.
Does anyone know a way to do this without requiring partialImplementation to inherit from interface?
The option you don't want
It is not clear what you intend to do. But one thing is for sure: in your solution the fnA() of partialImplementation has nothing to do with the fnA() of interface, since both classes are unrelated. Furthermore, in partialImplementation this function is not virtual.
So to get the partialImplementation's fnA() as a virtual function in a class derived from interface, the explicit call that you have exposed is the only way to proceed.
If you want to get rid of the boilerplate code, you have to make partialImplementation inheriting from interface. It will still be an abstract class that can't be instantiated, since fnB() is still missing.
class partialImplementation : public interface { ... };
class myClass : public partialImplementation {
public:
void fnB() const {cout << "fnB from myClass" << endl;}
};
Want to combine several partial implementations ?
It is not clear why you don't want this inheritance. If you want to combine several different partial implementations, in a mixin stile, but you want to avoid having several distinct interface sub-objects, you could opt for virtual inheritance:
class partialImplementationA : public virtual interface {
public:
void fnA() const {cout << "fnA from partial implementation A" << endl;}
};
class partialImplementationB : public virtual interface {
public:
void fnB() const {cout << "fnB from partial implementation B" << endl;}
};
class myClass : public virtual interface,
public partialImplementationA,
public partialImplementationB {
public:
};
Online demo
The inconvenience, is that the inheritance has to be declared virtual at all levels. But it allows to achieve the kind of things that you want to do without the boilerplate code.
Related
When designing an interface, someone recommended to use the non-virtual interface pattern. Can someone briefly outline what the benefits of this pattern are?
The essence of the non-virtual interface pattern is that you have private virtual functions, which are called by public non-virtual functions (the non-virtual interface).
The advantage of this is that the base class has more control over its behaviour than it would if derived classes were able to override any part of its interface. In other words, the base class (the interface) can provide more guarantees about the functionality it provides.
As a simple example, consider the good old animal class with a couple of typical derived classes:
class Animal
{
public:
virtual void speak() const = 0;
};
class Dog : public Animal
{
public:
void speak() const { std::cout << "Woof!" << std::endl; }
};
class Cat : public Animal
{
public:
void speak() const { std::cout << "Meow!" << std::endl; }
};
This uses the usual public virtual interface that we're used to, but it has a couple of problems:
Each derived animal is repeating code -- the only part that changes is the string, yet each derived class needs the whole std::cout << ... << std::endl; boilerplate code.
The base class can't make guarantees about what speak() does. A derived class may forget the new line, or write it to cerr or anything for that matter.
To fix this, you can use a non-virtual interface that is supplemented by a private virtual function that allows polymorphic behaviour:
class Animal
{
public:
void speak() const { std::cout << getSound() << std::endl; }
private:
virtual std::string getSound() const = 0;
};
class Dog : public Animal
{
private:
std::string getSound() const { return "Woof!"; }
};
class Cat : public Animal
{
private:
std::string getSound() const { return "Meow!"; }
};
Now the base class can guarantee that it will write out to std::cout and end with a new line. It also makes maintenance easier as derived classes don't need to repeat that code.
Herb Sutter wrote a good article on non-virtual interfaces that I would recommend checking out.
Here is a wiki article it a bit more in details with some examples. The essence is that you can ensure important conditions (like obtaining and releasing locks) in a central place in your base class while still allowing to derive from it to provide different implementations by using private or protected virtual functions.
Users of any class of the class hierarchy will always call the public interface which dispatches the calls to the not externally visible implementations.
So I recently accidentally called some virtual functions from the constructor of a base class, i.e. Calling virtual functions inside constructors.
I realise that I should not do this because overrides of the virtual function will not be called, but how can I achieve some similar functionality? My use-case is that I want a particular function to be run whenever an object is constructed, and I don't want people who write derived classes to have to worry about what this is doing (because of course they could call this thing in their derived class constructor). But, the function that needs to be called in-turn happens to call a virtual function, which I want to allow the derived class the ability to override if they want.
But because a virtual function gets called, I can't just stick this function in the constructor of the base class and have it get run automatically that way. So I seem to be stuck.
Is there some other way to achieve what I want?
edit: I happen to be using the CRTP to access other methods in the derived class from the base class, can I perhaps use that instead of virtual functions in the constructor? Or is much the same issue present then? I guess perhaps it can work if the function being called is static?
edit2: Also just found this similar question: Call virtual method immediately after construction
If really needed, and you have access to the factory.
You may do something like:
template <typename Derived, typename ... Args>
std::unique_ptr<Derived> Make(Args&&... args)
{
auto derived = std::make_unique<Derived>(std::forward<Args>(args));
derived->init(); // virtual call
return derived;
}
There is no simple way to do this. One option would be to use so-called virtual constructor idiom, hide all constructors of the base class, and instead expose static 'create' - which will dynamically create an object, call your virtual override on it and return (smart)pointer.
This is ugly, and what is more important, constrains you to dynamically created objects, which is not the best thing.
However, the best solution is to use as little of OOP as possible. C++ strength (contrary to popular belief) is in it's non-OOP specific traits. Think about it - the only family of polymorphic classess inside standard library are streams, which everybody hate (because they are polymorphic!)
I want a particular function to be run whenever an object is constructed, [... it] in-turn happens to call a virtual function, which I want to allow the derived class the ability to override if they want.
This can be easily done if you're willing to live with two restrictions:
the constructors in the entire class hierarchy must be non-public, and thus
a factory template class must be used to construct the derived class.
Here, the "particular function" is Base::check, and the virtual function is Base::method.
First, we establish the base class. It has to fulfill only two requirements:
It must befriend MakeBase, its checker class. I assume that you want the Base::check method to be private and only usable by the factory. If it's public, you won't need MakeBase, of course.
The constructor must be protected.
https://github.com/KubaO/stackoverflown/tree/master/questions/imbue-constructor-35658459
#include <iostream>
#include <utility>
#include <type_traits>
using namespace std;
class Base {
friend class MakeBase;
void check() {
cout << "check()" << endl;
method();
}
protected:
Base() { cout << "Base()" << endl; }
public:
virtual ~Base() {}
virtual void method() {}
};
The templated CRTP factory derives from a base class that's friends with Base and thus has access to the private checker method; it also has access to the protected constructors in order to construct any of the derived classes.
class MakeBase {
protected:
static void check(Base * b) { b->check(); }
};
The factory class can issue a readable compile-time error message if you inadvertently use it on a class not derived from Base:
template <class C> class Make : public C, MakeBase {
public:
template <typename... Args> Make(Args&&... args) : C(std::forward<Args>(args)...) {
static_assert(std::is_base_of<Base, C>::value,
"Make requires a class derived from Base");
check(this);
}
};
The derived classes must have a protected constructor:
class Derived : public Base {
int a;
protected:
Derived(int a) : a(a) { cout << "Derived() " << endl; }
void method() override { cout << ">" << a << "<" << endl; }
};
int main()
{
Make<Derived> d(3);
}
Output:
Base()
Derived()
check()
>3<
If you take a look at how others solved this problem, you will notice that they simply transferred the responsibility of calling the initialization function to client. Take MFC’s CWnd, for instance: you have the constructor and you have Create, a virtual function that you must call to have a proper CWnd instantiation: “these are my rules: construct, then initialize; obey, or you’ll get in trouble”.
Yes, it is error prone, but it is better than the alternative: “It has been suggested that this rule is an implementation artifact. It is not so. In fact, it would be noticeably easier to implement the unsafe rule of calling virtual functions from constructors exactly as from other functions. However, that would imply that no virtual function could be written to rely on invariants established by base classes. That would be a terrible mess.” - Stroustrup. What he meant, I reckon, is that it would be easier to set the virtual table pointer to point to the VT of derived class instead of keep changing it to the VT of current class as your constructor call goes from base down.
I realise that I should not do this because overrides of the virtual function will not be called,...
Assuming that the call to a virtual function would work the way you want, you shouldn't do this because of the invariants.
class B // written by you
{
public:
B() { f(); }
virtual void f() {}
};
class D : public B // written by client
{
int* p;
public:
D() : p( new int ) {}
void f() override { *p = 10; } // relies on correct initialization of p
};
int main()
{
D d;
return 0;
}
What if it would be possible to call D::f from B via VT of D? You will use an uninitialized pointer, which will most likely result in a crash.
...but how can I achieve some similar functionality?
If you are willing to break the rules, I guess that it might be possible to get the address of desired virtual table and call the virtual function from constructor.
Seems you want this, or need more details.
class B
{
void templateMethod()
{
foo();
bar();
}
virtual void foo() = 0;
virtual void bar() = 0;
};
class D : public B
{
public:
D()
{
templateMethod();
}
virtual void foo()
{
cout << "D::foo()";
}
virtual void bar()
{
cout << "D::bar()";
}
};
I have searched stack overflow but haven't found something that exactly answers my question. I have an interface class which contains only pure virtual functions which I would like to be implemented by classes which derive from this class.
I have an interface that I will call BaseInterface which defines functions that I would like to be overridden in all classes which derive from this interface. In this example, say there is only one pure virtual function called toImplement. I create a class called Base which inherits from BaseInterface and adds some functionality to the inherited pure virtual functions. Base is still an abstract class since it does not implement the functions in BaseInterface.
I have several classes which derive from Base which all benefit from the common functionality of Base but specify what happens when toImplement is run on their instances. These classes should all be concrete and satisfy all the requirements set by BaseInterface. Below I define one of these classes called Derived.
All of this works fine when BaseInterface and Base are not templated. The code compiles and runs fine without defining (1.) or implementing (2.) toImplement in Base.
However I would like toImplement to work with different types. From what I understand it is fine to have pure virtual functions in a templated class. I template BaseInterface and Base on some type T. When I don't define toImplement in Base (1.), I cannot compile since Base doesn't know which toImplement to use in tryUsingImplemented. If I now add the definition to Base, the code pre-compiles but the linker cannot find the implementation of Base::toImplement. Finally, if I both define and implement toImplement in Base (1. and 2.), the code compiles.
I don't like this because I have a dummy implementation of toImplement in Base and I never want this implementation to be run. Additionally, because Base implements toImplement, Derived is no longer required to implement it. This makes BaseInterface useless in my eyes.
Can sombody enlighten me on how to enforce the implementation of toImplement in Derived, without having to implement it in Base first if that is at all possible?
template <typename T>
class BaseInterface {
virtual void toImplement(T & t) = 0;
};
template <typename T>
class Base : public BaseInterface<T> {
bool m_useImplemented;
public:
explicit Base(bool useImplemented) : m_usedImplemented(useImplemented) {}
void tryUsingImplemented(T & t) {
if (m_useImplemented)
toImplement(t);
}
protected:
// 1: Defining toImplement pure virtual function in Base
virtual void toImplement(T & t);
};
// 2. Implementing a version of toImplement in Base which does nothing
template <typename T>
inline void Base<T>::toImplement(T & t) {
// do nothing
}
class Derived : public Base<int> {
public:
explicit Derived(bool useImplemented) : Base<int>(useImplemented) {}
protected:
// 3. implementing toImplement in Derived
void toImplement(T & t) {
std::cout << "Doing stuff for Derived" << std::endl;
}
};
For future reference, it would be helpful if you provided the compiler error message.
However, in this case I know. There are two errors in your code:
toImplement is private in BaseInterface.
The lookup in tryUsingImplemented will not look in the base class. You're facing the lookup in dependent bases problem. To fix it, write this->toImplement(t).
You need to declare toImplement as protected in BaseInterface if you intend to call it from a derived class. I have removed all the overriding methods from the derived classes and replaced the parameter type of Derived::toImplement with int, and it compiles fine. The latter is necessary because Derived is not a template, so you need to use the template parameter passed to Base.
#include <iostream>
template <typename T>
class BaseInterface {
protected:
virtual void toImplement(T & t) = 0;
};
template <typename T>
class Base : public BaseInterface<T> {
bool m_useImplemented;
public:
explicit Base(bool useImplemented) : m_useImplemented(useImplemented) {}
void tryUsingImplemented(T & t) {
if (m_useImplemented)
toImplement(t);
}
};
class Derived : public Base<int> {
public:
explicit Derived(bool useImplemented) : Base<int>(useImplemented) {}
protected:
// 3. implementing toImplement in Derived
void toImplement(int & t) {
std::cout << "Doing stuff for Derived" << std::endl;
}
};
Is it sufficient to define the method once to be virtual in the inheritance hierarchy to make polymorphism to work.
In the following example Der::f is not defined to be virtual but d2->f(); prints der2
I am using VS IDE (may be it is only there...)
class Base
{
public:
virtual void f() { std::cout << "base"; }
};
class Der : public Base
{
public:
void f() { std::cout << "der"; } //should be virtual?
};
class Der2 : public Der
{
public:
void f() { std::cout << "der2"; }
};
int main()
{
Der* d2 = new Der2();
d2->f();
}
Yes, polymorphism will work if you define method as a virtual only in your Base class. However, it is a convention I came across working with some large projects to always repeat virtual keyword in method declarations in derived classes. It may be useful when you are working with a lot of files with complex class hierarchy (many inheritance levels), where classes are declared in separate files. That way you don't have to check which method is virtual by looking for base class declaration while adding another derived class.
Everything that inherits from Base - directly or through several layers will have f() virtual as if the class declarion had explicitely placed virtual when f() was declared.
I have a class template where some methods are defined as virtual to give the ability for the user of my class to give an implementation for them in his derived class. Note that in my template class there is some non-virtual methods that makes use of the virtual one (a virtual class that should return a value is called in a non-virtual class).
Can you give me a simple example of a correct code where the virtual method of the parent class should return a value (but it's implementation is provided in a child class) and the value returned by the virtual method in the parent class is used in other methods of that class. Because I saw somewhere (for example here: Safely override C++ virtual functions) that this can cause some problems and the user defined method will note override the virtual method of the parent class.
Note: I program with Code::Blocks using g++ compiler.
EDIT: as requested here a simple example of what I want:
template<typename T>
class parent {
public:
// Public methods that user can call
int getSomething(T t);
void putSomething(T t, int x);
// public method that user should implement in his code
virtual float compute(T t) { }
// protected or private methods and attributes used internally by putSomething ...
float doComplexeThings(...); // this can call
};
The method compute() should be implemented by the user (the child class). However, this method compute() is called by putSomething() and doComplexeThings() for example.
If you can use C++11 features in your compiler then overrides can be tagged as so with the override special identifier:
float compute() override;
The above line in a derived class will cause a compiler error as the function does not override a member function in the base (incorrect signature, missing argument). But note that this must be done in each derived class, it is not a solution that you can impose from the base class.
From the base class you can only force the override by making the function pure virtual, but that changes the semantics. It does not avoid problems while overriding, but rather forces overriding in all cases. I would avoid this approach, and if you are to follow it and there is a sensible implementation for the base type, make the function virtual and provide a definition so that your derived classes's implementation can just call the functions the base type (i.e. you force the implementation, but in the simplest cases it will just forward the call to the parent)
You just have to make sure that the methods have the same signature (including const/mutable modifiers and argument types). You can use a pure virtual definition to provoke compiler errors if you fail to override the function in a subclass.
class parent {
public:
// pure virtual method must be provided in subclass
virtual void handle_event(int something) = 0;
};
class child : public parent {
public:
virtual void handle_event(int something) {
// new exciting code
}
};
class incomplete_child : public parent {
public:
virtual void handle_event(int something) const {
// does not override the pure virtual method
}
};
int main() {
parent *p = new child();
p->handle_event(1); // will call child::handle_event
parent *p = new incomplete_child(); // will not compile because handle_event
// was not correctly overridden
}
This question is asked in 2013. It's pretty old but I found something new which doesn't exist in the answers.
We need to understanding three concept is overload, overwrite, and hide.
Short answer, you want to overload the inheritance function from base class.
However, overload is the mechanism to add multiple behavior for function which needs all these functions under the same scale. But the virtual function is in the Base class obviously.
class A {
public:
virtual void print() {
cout << id_ << std::endl;
}
private:
string id_ = "A";
};
class B : A {
public:
using A::print;
void print(string id) {
std::cout << id << std::endl;
}
};
int main(int argc, char const *argv[]) {
/* code */
A a;
a.print();
B b;
b.print();
b.print("B");
return 0;
}
Add using A::print; in your derive class will do the work!
Though I don't feel it's a good idea since the philosophy behind the overload and inheritance is different, it may not a good idea to nest them together.