Create conditional an object on stack? - c++

What is the easiest way to create an object on stack based on a certain condition within the current scope?
Assume my current code is:
Base obj();
obj.print();
Now I want to change the code to 'plugin' a different derived class e.g. :
bool doBase=true;
doBase ? Base obj() : Derived obj();
obj.print();
But this of course does not work?
I know how to get this working, e.g. with an if, however my print in this example is in real world say 10-50 lines so this result in code duplication. Another approach is dynamically creating the objects, but I am curious there is a way to fix this without dynamically creating the objects.
bool doBase=true;
if (doBase) {
Base obj();
obj.print();
} else {
Derived obj();
obj.print(); // CODE DUPLICATION
}
Full snippet:
#include <iostream>
class Base {
virtual void print() { std::cout << "In base"<<std::endl; }
};
class Derived : public Base {
virtual void print() override { std::cout << "In derived"<<std::endl; }
};
int main() {
bool doBase=true;
doBase ? Base obj() : Derived obj();
obj.print();
doBase=false;
doBase ? Base obj2() : Derived obj2();
obj2.print();
}

You could use lambdas to wrap the repetitive code, eg:
#include <iostream>
class Base {
public:
virtual void print() { std::cout << "In base"<<std::endl; }
};
class Derived : public Base {
public:
virtual void print() override { std::cout << "In derived"<<std::endl; }
};
int main() {
auto print = [](Base &&obj){ obj.print(); };
auto doIt = [&print](bool doBase) { doBase ? print(Base{}) : print(Derived{}); };
doIt(true);
doIt(false);
}
Online Demo
Alternatively, use std::variant, eg:
#include <iostream>
#include <variant>
class Base {
public:
virtual void print() { std::cout << "In base"<<std::endl; }
};
class Derived : public Base {
public:
virtual void print() override { std::cout << "In derived"<<std::endl; }
};
int main() {
auto print = [](Base& obj){ obj.print(); };
auto doIt = [&print](bool doBase) {
std::variant<Base, Derived> v;
if (doBase) {
v = Base{};
} else {
v = Derived{};
}
std::visit(print, v);
};
doIt(true);
doIt(false);
return 0;
}
Online Demo

Related

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();
}

List of multiple class to run same function name C++ [duplicate]

This question already has answers here:
How to store object of different class types into one container in modern c++?
(2 answers)
Closed 3 years ago.
I have multiple classes with same function as below
class A
{
void display()
{
// display something
}
};
class B
{
void display()
{
// display something two
}
};
I want to store difference class at a list or a vector and loop to call the same function with same name
int main()
{
A * a;
B * b;
//list or vector to store object
std::vector < Something that can store different class > listofclass;
listofclass.emplace_back(a);
listofclass.emplace_back(b);
for (int i = 0; i < listofclass.size(); i++)
{
listofclass[i].display();
}
}
Is that possible to do like this?
Because there is separate classes, having different purpose, and now i try to group them together
Or there is other alternative way to achieve something like this
If you control the definition of A and B, you can write a common base class, and have them inherit it.
class can_display {
public:
virtual void display() = 0;
virtual ~can_display() = default;
};
class A : public can_display
{
void display() override
{
// display something
}
};
class B : public can_display
{
void display() override
{
// display something two
}
};
int main()
{
A a;
B b;
std::vector<can_display *> displayables;
displayables.push_back(&a);
displayables.push_back(&b);
for (can_display * displayable : displayables)
{
displayable->display();
}
}
As an alternative to changing the definition of A and B to inherit from a common base, you can have a wrapper that inherits.
template <typename T>
class can_display_impl {
T * wrapped;
public:
can_display_impl(T * wrapped) : wrapped(wrapped) {}
void display() override { wrapped->display(); }
}
template <typename T>
std::unique_ptr<can_display> make_can_display(T & wrapped) {
return std::make_unique<can_display_impl<T>>(&wrapped);
}
int main()
{
A a;
B b;
std::vector<std::unique_ptr<can_display>> displayables;
displayables.emplace_back(make_can_display(a));
displayables.emplace_back(make_can_display(b));
for (auto & displayable : displayables)
{
displayable->display();
}
}
You have two solutions for this problem:
Use inheritance and just make a abstract class that will be a interface for your classes. In class A and class B just inherit from that interface and in std::vector hold pointer to base class.
#include <vector>
#include <iostream>
#include <memory>
class Interface_display {
public:
virtual void display() = 0;
virtual ~Interface_display(){};
};
class A : public Interface_display
{
public:
void display() override
{
std::cout << "Display from A\n";
}
~A() override = default;
};
class B : public Interface_display
{
public:
void display() override
{
std::cout << "Display from B\n";
}
~B() override = default;
};
int main(void)
{
std::vector<std::unique_ptr<Interface_display>> v;
v.emplace_back(std::make_unique<A>());
v.emplace_back(std::make_unique<B>());
for (const auto &element: v) {
element->display();
}
}
And if you are using c++17, you could use std::variant and wrap objects of your class to std::variant:
#include <vector>
#include <iostream>
#include <variant>
class A
{
public:
void display()
{
std::cout << "Display from A\n";
}
};
class B
{
public:
void display()
{
std::cout << "Display from B\n";
}
};
int main(void)
{
using variant_t = std::variant<A, B>;
std::vector<variant_t> v;
v.emplace_back(A());
v.emplace_back(B());
for (auto &element: v) {
std::visit([](auto &x) { x.display(); }, element);
}
}
https://wandbox.org/permlink/8VBmziWzafbPZk99
A way to solve this problem is by using polymorphism. You make a superclass, which contains a pure virtual version of this function and let both A and B inherit from this class. By doing this, you can dynamic_cast any pointer of type A or B to a superclass type, on which you have defined the display function.
This will get you something like this
class C {
public:
virtual void display() = 0;
virtual ~C() = default;
};
class A : public C {
public:
void display() override {
std::cout << "A" << std::endl;
};
~A() override = default;
};
class B : public C {
public:
void display(){
std::cout << "B" << std::endl;
};
~B() override = default;
};
So you can do:
C* c = new A();
// You can put the types of C* in the same list, and iterate over this list and do on each element
c->display();
delete c;

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.

Is it possible to adapt the "Prototype pattern" to rvalue references?

I have a hierarchie of classes that implement the Prototype pattern and I would like to use move semantics to limit objects deep copy. I tried to adapted the pattern with a move() member function which meaning is that I do not need the original object anymore. Here is what I have so far:
#include <iostream>
#include <utility>
#include <vector>
struct base
{
virtual ~base() { }
virtual base* clone() const = 0;
virtual base* move() = 0;
};
struct derived1 : public base
{
derived1() { std::cout << "derived1::derived1()\n"; }
derived1(const derived1&) { std::cout << "derived1::derived1(const derived1&)\n"; }
derived1(derived1&&) { std::cout << "derived1::derived1(derived1&&)\n"; }
virtual ~derived1() { }
virtual base* clone() const { return new derived1(*this); }
virtual base* move() { return new derived1(std::move(*this)); }
};
struct derived2 : public base
{
derived2() { std::cout << "derived2::derived2()\n"; }
derived2(const derived2&) { std::cout << "derived2::derived2(const derived2&)\n"; }
derived2(derived2&&) { std::cout << "derived2::derived2(derived2&&)\n"; }
virtual ~derived2() { }
virtual base* clone() const { return new derived2(*this); }
virtual base* move() { return new derived2(std::move(*this)); }
};
std::vector<base*> vec;
void foo(const base& obj)
{
vec.push_back(obj.clone());
}
void foo(base&& obj)
{
vec.push_back(obj.move());
}
int main()
{
derived1 d1;
derived2 d2;
foo(d1);
foo(d2);
foo(derived1());
foo(derived2());
}
When I run it, it show that the good constructors are used:
derived1::derived1()
derived2::derived2()
derived1::derived1(const derived1&)
derived2::derived2(const derived2&)
derived1::derived1()
derived1::derived1(derived1&&)
derived2::derived2()
derived2::derived2(derived2&&)
So far, it seems good. I am just not sure if this is a standard compliant usage of the rvalue references. Is there a point I did not think of that would produce undesirable results?
For recurring method definition I prefer CRTP. For your case I'd declare something like:
template<typename TDerived>
class virtually_clonable : public base
{
public:
virtual base* clone() override
{
return new TDerived(*AsDerived());
}
virtual base* move() override
{
return new TDerived(std::move(*AsDerived()));
}
private:
TDerived* AsDerived()
{
return static_cast<TDerived*>(this);
}
};
And while implementing the classes:
class derived1 : public virtually_clonable<derived1>
{
public:
/* your ctors goes here*/
/* no need to implement clone/move again */
};
class derived2 : public virtually_clonable<derived2>
{
public:
/* your ctors goes here*/
/* no need to implement clone/move again */
};
By the way you may want to return shared_ptr objects instead of raw pointers. That is usually the case for clonable types instead of unique_ptr.