Unexpected behaviour when using inheritance - c++

I have a Base class, which is then inherited by Foo, and Foo is in turn inehrited by Bar.
Here is the header file base.h for my Base class:
#pragma once
class Base {
public:
void runExample();
private:
virtual void print();
};
And the implementation base.cpp:
#include "base.h"
void Base::runExample() {
print();
}
void Base::print() {};
Here is the header file foo.h for my Foo class:
#pragma once
#include "../base/base.h"
class Foo : public Base {
public:
Foo();
private:
void print();
const char* toPrint;
};
And the implementation foo.cpp:
#include "foo.h"
Foo::Foo() {
toPrint = "Hello Foo";
}
void Foo::print() {
std::cout << toPrint << std::endl;
}
Here is the header file bar.h for my Bar class:
#pragma once
#include "../foo/foo.h"
class Bar : public Foo {
public:
Bar();
private:
const char* toPrint; // "overrides" toPrint from parent class Foo?
};
And the implementation bar.cpp:
#include "bar.h"
Bar::Bar() {
toPrint = "Hello Bar";
}
And finally, my main function:
#include "../bar/bar.h"
int main() {
Bar bar = Bar();
bar.runExample();
}
So, I have this kind of relationship between the classes:
Bar is a Foo which is a Base.
What I was expecting to see in the output was "Hello Bar", but what I actually see is "Hello Foo".
If I "override" the print method declared in Foo in Bar to print toPrint then I get the expected result, however this seems to break the point of inheritance; i.e. why would I need to re-define the functionality when it's already defined.
What I am expecting is that when Bar.print() is invoked, it uses Foos implementation, but the actual field toPrint has been "replaced" with the value inside the Bar implementation.
I am very new to C++, and I'm coming from a Kotlin background. Forgive me if this is like C++ 101 basics, but I'm pretty confused as to why this is happening. Could anyone point me in the right direction?

In C++, data members cannot be "overridden" as you expect, and a reference to toPrint will not be dynamically bound to equally named data members in subclasses.
With
class Bar : public Foo {
...
const char* toPrint; // "overrides" toPrint from parent class Foo?
};
you introduce a member variable Bar::toPrint next to Foo::toPrint, which is inherited. The code
void Foo::print() {
std::cout << toPrint << std::endl;
}
will always stick to the toPrint-member in his scope, i.e. to Foo::toPrint.
The following code illustrates this behaviour:
struct Base {
const char* toPrint = "Base";
virtual void print() const { cout << toPrint << std::endl; }
};
struct Derived: public Base {
const char* toPrint = "Derived";
void printBoth() const { cout << "own:" << toPrint << "; inherited: " << Base::toPrint << std::endl; }
};
int main() {
Derived d;
cout << "call inherited method print:" << std::endl;
d.print();
cout << "call method printBoth, showing both data members:" << std::endl;
d.printBoth();
}
Output:
call inherited method print:
Base
call method printBoth, showing both data members:
own:Derived; inherited: Base

Related

c++ how to overwrite method in subclass

I have some code I'm trying to get to work, I'm open to other suggestions on how to do this. Basically, I have some base class that I want a bunch of subclasses to inherit. I then have a function that needs to call the subclass version of this method.
#include <iostream>
using namespace std;
//my base class
class BaseClass {
public:
void myMethod(){
std::cout << "Base class?" << std::endl;
}
};
/my subclass
class SubClass1: public BaseClass{
public:
void myMethod(){
std::cout << "Subclass?" << std::endl;
}
};
//method that I want to call SubClass.myMethod(). I cannot declare this as
//SubClass1 because there will be multiple of these.
void call_method(BaseClass object){
return object.myMethod();
}
int main()
{
BaseClass bc;
SubClass1 sb1;
//works how I expect it to
sb1.myMethod();
//I want this to also print "Subclass?"
//but it prints "Base class?".
call_method(sb1);
return 0;
}
Thanks for your help
You need to declare the member function in the base class as virtual. For example
virtual void myMethod() const {
std::cout << "Base class?" << std::endl;
}
And in the derived class to override it
void myMethod() const override {
std::cout << "Subclass?" << std::endl;
}
And the function call_method must have a parameter that represents a reference to base class object
void call_method( const BaseClass &object){
object.myMethod();
}

why is the child function not getting called while inheriting a singleton in c++

I have the following test code. Here, the output is "from parent", how can I call the child function? Why is the child function not getting called? is is recommended to inherit from a singleton?
#include <iostream>
using namespace std;
class Singleton
{
public:
static Singleton& getInstance()
{
static Singleton s;
return s;
}
virtual void func()
{
cout << "from parent" << endl;
}
};
class Child : public Singleton
{
public:
void func() override
{
cout << "from child" << endl;
}
};
int main()
{
Singleton& s = Child::getInstance();
s.func();
}
Right now, Singleton::getInstance always returns a Singleton. Child doesn't have its own version of getInstance, so Child::getInstance() resolves to a call to Singleton::getInstance() which returns a Singleton, not a Child. If we use the CRTP, we can make it so Singleton::getInstance actually knows the derived type we're trying to get an instance of:
#include <iostream>
#include <type_traits>
template <class Derived>
class Singleton
{
public:
static Derived& getInstance()
{
// Assert that the template arg really is derived from the appropriate instantiation of the base class template
static_assert(std::is_base_of<Singleton<Derived>, Derived>::value);
static Derived s;
return s;
}
virtual void func()
{
std::cout << "from parent" << std::endl;
}
};
class Child : public Singleton<Child>
{
public:
void func() override
{
std::cout << "from child" << std::endl;
}
};
int main()
{
auto& s = Child::getInstance(); // s is a Child here
s.func(); // Outputs "from child" as expected
}

Is there a way to wrap a function call in or overload a functions call?

My aim is to have a class that inherits from another class in C++ and overloads all of the parents class methods in an identical fashion.
So when a method is called some code is run, the original method is called and a bit more code is run all in the derived class overload method.
class Base
{
Base() {}
~Base() {}
void base_method()
{
// Does something.
}
}
template<class T>
class ClassWrapper : public T
{
public:
ClassWrapper(T base) : T( base ) {}
~ClassWrapper() {}
void wrap_function()
{
// multithread block {
// call base method within multithread block.
this->base_method();
// }
}
}
int main()
{
Base B;
ClassWrapper<Base> C( B );
C.base_method();
return 0;
}
Ideally nothing would be known about the base class but all of its methods could be overridden.
I'm not sure if this is even possible but if it is any suggestions would be great!
With inheritance, you might do:
class Base
{
Base() {}
virtual ~Base() {}
virtual void base_method()
{
// Does something.
}
};
class BaseWrapper : public Base
{
public:
BaseWrapper(Base base) : Bas( base ) {}
void base_method() override
{
// Some code ...
Base::base_method();
// Some code ...
}
}
int main()
{
Base B;
BaseWrapper C( B );
C.base_method();
}
Static polymorphism achieved through CRTP (Curiously Recurring Template Pattern) might be beneficial for you.
Read more about CRTP here and here.
Imagine you have a Wrapper class like:
template <typename Impl>
class Wrapper {
public:
Wrapper() {}
~Wrapper() {}
void some_preparation() {
std::cout << "Wrapper work!" << std::endl;
}
};
and then you have your actual class like:
class MyFoo : public Wrapper<MyFoo> {
public:
MyFoo() {}
~MyFoo() {}
void foo() {
Wrapper::some_preparation();
std::cout << "Derived work!" << std::endl;
}
};
and, eventually, you can use above code like:
MyFoo wrappedFoo;
wrappedFoo.foo();
The result would be:
Wrapper work!
Derived work!
Jarod's answer is a very good one for your question. However, I would like to add an answer more focused on your chosen design rather than the implementation.
Although you said that you want to "overloads all of the parents class methods in an identical fashion", your goal ("the original method is called and a bit more code is run all in the derived class overload method") indicates that it is slightly different.
The first one may indicate inheritance, but the second one may point to factory abstract design pattern (composition over inheritance):
#include<iostream>
class AbstractBar
{
public:
virtual void bar_method() = 0;
};
class Bar1 : public AbstractBar
{
public:
void bar_method() {
std::cout << "Bar 1" << std::endl;
}
};
class Bar2 : public AbstractBar
{
public:
void bar_method() {
std::cout << "Bar 2" << std::endl;
}
};
class Foo
{
public:
Foo(AbstractBar* bar_) : bar(bar_) { }
void foo_method() {
bar->bar_method();
std::cout << "Foo" << std::endl;
}
private:
AbstractBar* bar;
};
int main() {
Bar1 bar;
Foo foo(&bar);
foo.foo_method();
}
Being the output of the code:
Bar 1
Foo
Or a simplified version (based on your needs):
#include<iostream>
class Bar {
public:
void bar_method() {
std::cout << "Bar" << std::endl;
}
};
class Foo {
public:
Foo(Bar* bar_) : bar(bar_) { }
void foo_method() {
bar->bar_method();
std::cout << "Foo" << std::endl;
}
private:
Bar* bar;
};
int main() {
Bar bar;
Foo foo(&bar);
foo.foo_method();
}

How can I pass base class pointer in a CRTP implementation

I am converting my code having plain inheritance with pure virtual methods into CRTP to avoid overhead of virtual methods (see here).
The conversion works perfectly fine till I remove the comment on call method in the CRTP implementation (It gives compilation error: use of undeclared identifier 'T') How do I implement the same call method in CRTP which gives no problem in plain inheritance? In other words, is it possible to pass a pointer to base class as in plain inheritance?
Of course, I can solve the problem by moving the call method inside the class template, but for my use case, it does not belong there (I have not given my actual code here, which is quite long). Any ideas?
Code before conversion looks like:
#include <iostream>
class Base
{
public:
void interface() {
implementation();
}
virtual void implementation() = 0;
};
class Derived1 : public Base
{
public:
void implementation() {
std::cout << "Hello world 1" << std::endl;
}
};
class Derived2 : public Base
{
public:
void implementation() {
std::cout << "Hello world 2" << std::endl;
}
};
void call(Base *b) {
b->interface();
// ... do other things ...
}
int main() {
Derived1 d1;
Derived2 d2;
call(&d1);
call(&d2);
}
Code after conversion (CRTP) looks like:
#include <iostream>
template <class T>
class Base
{
public:
void interface() {
static_cast<T*>(this)->implementation();
}
};
class Derived1 : public Base<Derived1>
{
public:
void implementation() {
std::cout << "Hello world 1" << std::endl;
}
};
class Derived2 : public Base<Derived2>
{
public:
void implementation() {
std::cout << "Hello world 2" << std::endl;
}
};
//void call(Base<T> *b) {
// b->interface();
// // ... do other things ...
//}
int main() {
Derived1 d1;
Derived2 d2;
//call(&d1);
//call(&d2);
d1.interface();
d2.interface();
}
You missed some syntax. Correct declaration:
template<class T> // <--- this was missing
void call(Base<T> *b) {
b->interface();
}

Injecting a function into a subclass

Is it possible to do such things in C++14. I have a base class as follows:
#include <iostream>
class AbstractElement;
class ConcreteElement;
class SuperConcreteElement;
class B
{
public:
void bar(AbstractElement*)
{
std::cout << "Abstract element" << std::endl;
}
void bar(ConcreteElement*)
{
std::cout << "Concrete element" << std::endl;
}
void bar(SuperConcreteElement*)
{
std::cout << "Super concrete element" << std::endl;
}
};
class AbstractElement
{
public:
virtual void foo() = 0;
};
class ConcreteElement : public AbstractElement
{
private:
B _b;
public:
void foo()
{
_b.bar(this); //1
}
};
class SuperConcreteElement : public AbstractElement
{
private:
B _b;
public:
void foo()
{
_b.bar(this); //2
}
};
int main()
{
AbstractElement *e = new ConcreteElement();
e -> foo(); //Prints Concrete element
}
As you can see at //1 and //2, the function's body is completely similar. But I can't quite move it into a base class because of depending on the static type of this. In spite of that fact, I wouldn't like to write absolutely the same code every time I need to add one more subclass of AbstractElement. So, I need some kind of mechanism which provides us with the facility to inject code into a function.
As long as marcos are not very desirable solution, I'd like to ask about some tricks that can be done in C++14 for solving such a problem.
Yes, it is possible using CRTP:
#include <iostream>
class AbstractElement;
class ConcreteElement;
class SuperConcreteElement;
class B
{
public:
void bar(AbstractElement*)
{
std::cout << "Abstract element" << std::endl;
}
void bar(ConcreteElement*)
{
std::cout << "Concrete element" << std::endl;
}
void bar(SuperConcreteElement*)
{
std::cout << "Super concrete element" << std::endl;
}
};
class AbstractElement
{
public:
virtual void foo() = 0;
};
template <class T>
class CRTPAbstractElement : public AbstractElement
{
B _b;
public:
virtual void foo()
{
T* t = dynamic_cast<T *>(this);
_b.bar(t);
}
};
class ConcreteElement : public CRTPAbstractElement<ConcreteElement>
{
};
class SuperConcreteElement : public CRTPAbstractElement<SuperConcreteElement>
{
};
int main()
{
AbstractElement *e = new ConcreteElement();
e -> foo(); //Prints Concrete element
}
By adding an intermediate CRTP class we are able to cast a pointer to the base class to a pointer to the derived class. Thus solving the issue of code duplication.