I have base class A which has factory method to create instances of derived classes B and C. B and C has start() overridden. There is do_work() which calls getInstance() and then calls start(). Now labmda inside spawn() does not store the instance of captures this pointer. So there is a scope problem. If I pass instance(boost::shared_ptr) to start explicitly and then capture it in lambda, then it works. How do I avoid passing instance to start()?
class B : public A {
public:
void start(){
boost::spawn(io_service, [this](boost::asio::yield_context yield)
{
// work
});
}
}
class C: public A {
public:
void start(){
boost::spawn(io_service, [this](boost::asio::yield_context yield)
{
// work
});
}
}
do_work() {
auto object = A::getInstance(); // this returns boost::shared_ptr and it does not store that instance
object->start();
}
class A {
public:
virtual void start () =0;
static boost::shared_ptr<A> getInstance() {
return boost::shared_ptr<A>(new B());
}
}
You should use enable_shared_from_this:
Live On Coliru
#define BOOST_COROUTINES_NO_DEPRECATION_WARNING
#include <boost/enable_shared_from_this.hpp>
#include <boost/asio.hpp>
#include <boost/asio/spawn.hpp>
boost::asio::io_service io_service;
class A : public boost::enable_shared_from_this<A> {
public:
virtual void start() = 0;
static boost::shared_ptr<A> getInstance();
};
class B : public A {
public:
void start() {
auto self = shared_from_this();
boost::asio::spawn(io_service, [self](boost::asio::yield_context /*yield*/) {
// work
});
}
};
class C : public A {
public:
void start() {
auto self = shared_from_this();
boost::asio::spawn(io_service, [self](boost::asio::yield_context /*yield*/) {
// work
});
}
};
/*static*/ boost::shared_ptr<A> A::getInstance() { return boost::shared_ptr<A>(new B()); }
void do_work() {
auto object = A::getInstance(); // this returns boost::shared_ptr and it does not store that instance
object->start();
}
int main() {
}
Honestly, I don't know why the compiler let this pass. The start function doesn't exist in the A world.
Classes B and C haven't overridden anything unless there is a virtual function in their base class to override. Add a pure virtual start to class A, then decorate the B and C start functions with virtual. Then will those two classes have overridden something. I suspect that will result in the behavior you're expecting.
class A {
public:
static boost::shared_ptr<A> getInstance() {
return boost::shared_ptr<A>(new B());
}
virtual void start()=0;
};
class B : public A {
public:
virtual void start() {
// stuff specific to class B
}
};
class C : public A {
public:
virtual void start() {
// stuff specific to class C
}
};
Related
I have a interface where I am using the factory pattern to create an instance of the object and store it in a unique_ptr. I also have a MockInterface which I would like to use in my tests to not call the actual production code. However when I run my tests the production interface is called instead of the mock. What am I doing wrong??
Interface.hpp
class Interface
{
Interface() {};
virtual ~Interface() = default;
virtual int foo() = 0;
virtual int bar() = 0;
static std::unique_ptr<Interface> create();
};
Interface.cpp
#include "Interface.hpp"
#include "Impl.hpp"
std::unique_ptr<Interface> Interface::create()
{
return std::unique_ptr<Interface> { new Impl() };
}
Impl.hpp
class Impl : public Interface
{
Impl() {};
~Impl() {};
virtual int foo();
virtual int bar();
};
Impl.cpp
#include "Interface.hpp"
#include "Impl.hpp"
int Impl::foo()
{
return 2;
}
int Impl::bar()
{
return 2;
}
class MockInterface : public Interface
{
MockInterface() {};
~MockInterface() {};
MOCK_METHOD(int, foo, (), (override));
MOCK_METHOD(int, bar, (), (override));
}
lib.cpp
#include "Interface.hpp"
class Foo
{
public:
Foo() { inst = Interface::create(); }
virtual ~Foo() = default;
void some_function();
private:
std::unique_ptr<Interface> inst;
}
void Foo::some_function()
{
int foo_ret = inst->foo();
int bar_ret = inst->bar();
}
test.cc
std::unique_ptr<Interface> Interface::create()
{
std::unique_ptr<MockInterface> mock { new MockInterface() };
EXPECT_CALL(*mock, foo()).Times(1);
EXPECT_CALL(*mock, bar()).Times(1);
return mock;
}
TEST_F(fixture, test_foo)
{
// This will pass but I will get an error "mock object never deleted"
// Will also leave my terminal in a bad state
Foo *obj = new Foo();
obj->some_function();
// This will fail also leaving my terminal in a bad state
Foo obj2;
obj2.some_function();
}
some_function() calls Interface::create(), which has not been mocked, so it's still going to give you back a unique pointer pointing to an Impl object, not a MockInterface object.
To solve this you can either mock out Interface::create to have it return your mocked object, or have some_function receive a pointer/reference to Interface as a parameter instead of calling Interface::create itself. Then just pass it your mocked object.
The simplest way to mock the create function is to just redefine it for your tests. Exclude Interface.cpp from your test program since the function can only be defined once
std::unique_ptr<Interface> Interface::create()
{
std::unique_ptr<MockInterface> mock { new MockInterface() };
EXPECT_CALL(*mock, foo()).Times(1);
return mock;
}
TEST_F(fixture, test_foo)
{
some_function();
}
To provide different implementations for each test you can do something like this:
std::function<std::unique_ptr<Interface>()> creator;
std::unique_ptr<Interface> Interface::create()
{
return creator();
}
TEST_F(fixture, test_foo)
{
creator = []() {
std::unique_ptr<MockInterface> mock { new MockInterface() };
EXPECT_CALL(*mock, foo()).Times(1);
return mock;
};
// Will call Interface::create which will call creator()
some_function();
}
I have c++ library with code following code structure:
#include <vector>
std::vector<Base*> UserClasses;
int main(int argc,char** argv)
{
Init(argc,argv)
while(true)
{
for(auto* class : UserClasses){
class->start();
}
DoStuff();
for(auto* class : UserClasses){
class->update();
}
DoStuff();
}
Shutdown();
}
Base class is interface class with virtual methods.Like this:
class Base
{
public:
Base();
virtual ~Base();
virtual void start() = 0;
virtual void update() = 0;
};
The user will write his own classes like this:
class MyClass : public Base
{
public:
MyClass ();
~MyClass ();
virtual void start() override
{
//userstaff
};
virtual void update() override
{
//userstaff
};
};
I want to allow user to include my library and headers in his project, write his own child classes and compile project into executable.
But how can my library create instance of user classes?
It doesn't know anything about them.
Is it possible somehow create instance of class within header file and push it to vector?
I saw that it can be done by initializing static variables because it happens before main but I don't understand how to implement it.
As properly mentioned in the comments, do not define main in a library. Also, avoid non-const global variables, since this is a bad thing (tm). Instead, define a function and pass UserClasses to it directly. And it is better to encapsulate all the state you have in a class:
class Main {
public:
Main(int argc, char** argv) {
Init(argc, argv);
}
int run(const std::vector<std::unique_ptr<Base>>& user_classes)
{
while(true)
{
for(const auto& class : user_classes){
class->start();
}
DoStuff();
for(const auto& class : user_classes){
class->update();
}
DoStuff();
}
Shutdown();
}
private:
void DoStuff();
void Shutdown();
// ...
};
it can be done by initializing static variables
Yes, here's an example.
This is similar to #fabian's answer, but:
You don't need to manually register the classes.
The classes are not constructed automatically, you do it when you need them.
run on gcc.godbolt.org
#include <cstddef>
#include <iostream>
#include <memory>
#include <vector>
class BaseLow
{
template <typename T> friend class Base;
using factory_func_t = std::unique_ptr<BaseLow>(*)();
static std::vector<factory_func_t> &GetFactoryFuncsMutable()
{
static std::vector<factory_func_t> ret;
return ret;
}
public:
virtual ~BaseLow() {}
virtual void foo() = 0;
static std::vector<factory_func_t> &GetFactoryFuncs()
{
return GetFactoryFuncsMutable();
}
};
template <typename T>
class Base : public BaseLow
{
static std::nullptr_t RegisterSelf()
{
GetFactoryFuncsMutable().push_back([]() -> std::unique_ptr<BaseLow>
{
return std::make_unique<T>();
});
return nullptr;
}
inline static const std::nullptr_t dummy = RegisterSelf();
// Force `dummy` to be instantiated.
static constexpr std::integral_constant<decltype(&dummy), &dummy> dummy_helper{};
};
struct A : Base<A>
{
void foo() override
{
std::cout << "I'm A!\n";
}
};
struct B : Base<B>
{
void foo() override
{
std::cout << "I'm B!\n";
}
};
int main()
{
std::vector<std::unique_ptr<BaseLow>> objects;
for (const auto &func : BaseLow::GetFactoryFuncs())
objects.push_back(func());
for (auto &obj : objects)
obj->foo();
}
But how can my library create instance of user classes?
You can't but you can provide the user with a convenient way of adding a instance. You could e.g. provide a template class that registers an instance of a class in the constructor which allows the user to add an instance by simply defining an instance of this class.
Example
(Static) Library
Base.h
int main(int, char**);
template<typename T>
class BaseRegistrar
{
public:
BaseRegistrar();
};
class Base
{
public:
Base();
virtual ~Base();
virtual void start() = 0;
virtual void update() = 0;
private:
static std::vector<std::unique_ptr<Base>>& GetBaseInstances();
friend int main(int, char**);
template<typename T>
friend class BaseRegistrar;
};
template<typename T>
BaseRegistrar<T>::BaseRegistrar()
{
Base::GetBaseInstances().emplace_back(new T);
}
Base.cpp
#include "Base.h"
Base::Base(){}
Base::~Base(){}
std::vector<std::unique_ptr<Base>>& Base::GetBaseInstances()
{
static std::vector<std::unique_ptr<Base>> instances;
return instances;
}
main.cpp
#include "Base.h"
int main(int argc,char** argv)
{
for(auto& clazz : Base::GetBaseInstances()){
clazz->start();
}
for(auto& clazz : Base::GetBaseInstances()){
clazz->update();
}
}
Executable
MyClass.cpp
#include "Base.h"
#include <iostream>
class MyClass : public Base
{
public:
MyClass ()
{}
~MyClass ()
{}
virtual void start() override
{
std::cout << "MyClass::start()\n";
}
virtual void update() override
{
std::cout << "MyClass::update()\n";
}
};
// adds an instance of the class to the list
BaseRegistrar<MyClass> registrar;
Output
MyClass::start()
MyClass::update()
Consider this trivial C++11 inheritance example:
class A
{
public:
virtual void func() = 0;
};
class B : public A
{
public:
void func() { func1(); /* Wish this could be func1() or func2()! */ };
void func1() { /* Does one thing */ };
void func2() { /* Does another thing */ };
};
void doSomeStuff(A &a)
{
a.func();
}
int main()
{
B b;
doSomeStuff(b);
return 0;
}
I'm trying to make it so that I don't have to modify (or duplicate) class A's definition or the function doSomeStuff, but I want the invocation of a.func() to call either func1() or func2() of B. Ideally I'd change the line doSomeStuff(b) to something like doSomeStuff(b.butWithFunc1) but I'd also be OK with some way to modify B's version of func() so that it can make the decision internally to call func1 or func2 based on some parameter.
The same object of type B may have to sometimes call func1 or func2 during an invocation of func, so I can't use a persistent member of class B to decide. Adding a parameter to func() would make this trivial as well, but that's not something I can do either.
I'm kind of wondering if there's some way to add to class B a function that returns a mutated version of class B which calls func2() from func(), or if I can play some tricks with function pointers or something. However, something tells me I'm Doing It Wrong and the obvious solution is staring me in the face.
If it helps for context, class A is similar to a std::lock_guard, and it works fine for things like semaphores and mutexes (for which there is only one definition of lock and unlock), but class B in this example is a R/W lock - so there's a "readLock" and "writeLock", and I'd like to be able to say something like "auto lock this RW lock as a read lock" without having to duplicate/break the auto lock code.
For instance:
{
A_AutoSem(myMutex); // calls lock() on myMutex
//... do some stuff
// end of the block, ~A_AutoSem calls unlock on myMutex
}
{
A_AutoSem(B_RWLock); // how do I say here "call readLock"?
// ... do some stuff
// end of the block ~A_AutoSem should call "readUnlock" on B_RWLock
}
Simply define some additional classes to call func1() and func2(), and then pass those classes to doSomeStuff() instead of passing B directly.
Try something like this:
class A
{
public:
virtual void func() = 0;
};
class B
{
public:
void func1() { /* Does one thing */ };
void func2() { /* Does another thing */ };
};
class C1 : public A
{
private:
B &m_b;
public:
C1(B &b) : m_b(b) {}
void func() override { m_b.func1(); }
};
class C2 : public A
{
private:
B &m_b;
public:
C2(B &b) : m_b(b) {}
void func() override { m_b.func2(); }
};
void doSomeStuff(A &a)
{
a.func();
}
int main()
{
B b;
{
C1 c(b);
doSomeStuff(c);
}
{
C2 c(b);
doSomeStuff(c);
}
return 0;
}
Live Demo
Alternatively:
class A
{
public:
virtual void func() = 0;
};
class B
{
private:
void func1() { /* Does one thing */ };
void func2() { /* Does another thing */ };
public:
class C1 : public A
{
private:
B &m_b;
public:
C1(B &b) : m_b(b) {}
void func() override { m_b.func1(); }
};
class C2 : public A
{
private:
B &m_b;
public:
C2(B &b) : m_b(b) {}
void func() override { m_b.func2(); }
};
};
void doSomeStuff(A &a)
{
a.func();
}
int main()
{
B b;
{
B::C1 c(b);
doSomeStuff(c);
}
{
B::C2 c(b);
doSomeStuff(c);
}
return 0;
}
Live Demo
I am very new to c++ so I am trying to get a feeling of how to do things the right way in c++. I am having a class that uses one of two members. which one gets determined at instantiation. It looks something like
main() {
shared_pointer<A> a = make_shared<A>();
if ( checkSomething ) {
a->setB(make_shared<B>());
} else {
a->setC(make_shared<C>());
}
a->doStuff();
class A {
public:
doStuff() {
/*here I want to do something like call
m_b->doStuff() if this pointer is set and m_c->doStuff() if
that pointer is set.*/
}
setB( B* p ) { m_b = p; }
setC( C* p ) { m_c = p; }
B* m_b;
C* m_c;
}
}
B and C are some classes with doStuff() member function
There are many members like doStuff. Ideally I would avoid checking for nullptr in each of them. What is the best/most efficient/fastest way to create a switch between those two members?
Is there a way to use a static pointer so that I have a member
static **int m_switch;
and do something like
m_switch = condition ? &m_b : &m_c;
and call
*m_switch->doStuff();
Does the compiler here also replace the extra pointer hop because it is a static?
Is there any other smart way to do those switches?
Normally, class A would be an interface class, which both B and C would inherit and implement. But it sounds like you cannot do this for whatever reason.
Since you want to emulate this, you can start by making the interface:
class A_interface
{
public:
virtual void doStuff() = 0;
virtual void doThings() = 0;
virtual void doBeDoBeDo() = 0;
};
And then you make a template wrapper:
template< class T >
class A : public A_interface
{
public:
void doStuff() override { target.doStuff(); }
void doThings() override { target.doThings(); }
void doBeDoBeDo() override { target.doBeDoBeDo(); }
private:
T target;
};
This essentially does half of what your own example class A was trying to do, but now you can use a common interface. All you need to do is construct the correct templated version you want:
std::shared_ptr<A_interface> a;
if( checkSomething ) {
a = std::make_shared<A<B>>();
} else {
a = std::make_shared<A<C>>();
}
a->doStuff();
You need to have both members implement a common interface to use them similarly. But in order to do that, you need to define the interface and relay the calls to the B and C classes.
// existing classes
class B
{
public:
void doStuff() { std::cout << "B"; }
};
class C
{
public:
void doStuff() { std::cout << "C"; }
};
// define your interface
class I
{
public:
virtual void doStuff() = 0;
};
// new classes
class D : public B, public I
{
public:
void doStuff() override { B::doStuff(); }
};
class E : public C, public I
{
public:
void doStuff() override { C::doStuff(); }
};
// your A class
class A
{
public:
D* b = nullptr; // now type D
E* c = nullptr; // now type E
// your toggle
I* getActive()
{
if (b)
return b;
else
return c;
}
// simple doStuff() function
void doStuff()
{
getActive()->doStuff();
}
};
int main()
{
A a;
if (true)
a.b = new D; // need to initialize as D
else
a.c = new E; // need to initialize as E
a.doStuff(); // prints B
}
But typing this up made me realize that defining D and E could get really tiresome and against what you're trying to save. However, you can define a template to create them like #paddy has done.
There's no one-size-fits-all solution for your problem. What to use depends on your particular problem. A few possible answers:
Interfaces
Strategy Pattern
Pointers (to hold a function or class which implements doStuff)
An interface is like a contract. Any class which inherits from the interface must implement its members. For instance,
class IDoesStuff
{
public:
virtual ~IDoesStuff() {};
virtual void DoStuff() = 0;
};
Can now be used by other classes:
class Foo : public IDoesStuff
{
public:
virtual void DoStuff()
{
// ....
}
};
class Bar : public IDoesStuff
{
public:
virtual void DoStuff()
{
// ....
}
};
And now, in general, one may do:
Foo foo;
IDoesStuff *stuffDoer= &foo;
stuffDoer->doStuff();
This can be used in your particular use case as follows:
class A
{
IDoesStuff *stuffDoer; // Initialize this at some point.
public:
void doStuff() { stuffDoer->doStuff(); }
};
First you must change your memebr variables m_b and m_c to std::shared_ptr.
Add a member variable of type std::function(void()) to hold the target function you want to call. In your sample it is do_stuf.
In your setter functions you can bind target function to your std::function and in do_stuf just call std::function.
(You need a C++11 compiler)
class B
{
public:
void doStuff()
{
}
};
class C
{
public:
void doStuff()
{
}
};
class A
{
public:
void doStuff()
{
m_target_function();
}
void setB(std::shared_ptr<B> p)
{
m_b = p;
m_target_function = std::bind(&B::doStuff, m_b.get());
}
void setC(std::shared_ptr<C> p)
{
m_c = p;
m_target_function = std::bind(&C::doStuff, m_c.get());
}
std::shared_ptr<B> m_b;
std::shared_ptr<C> m_c;
std::function<void()> m_target_function;
};
int _tmain(int argc, _TCHAR* argv[])
{
std::shared_ptr<A> a = std::make_shared<A>();
bool use_B = false;
if (use_B)
{
a->setB(std::make_shared<B>());
}
else
{
a->setC(std::make_shared<C>());
}
a->doStuff();
}
Is it possible to have a derived class to have two sets of the same virtual functions as the base class? I'm looking to do something like the following. The idea being able to choose between two sets of function pointers.
class Base
{
virtual void func1;
virtual void func2;
};
class Derived: Base
{
float somemember;
void somefunction()
{
Base* func = this->derived_functions1;
}
class derived_functions1
{
virtual void func1()
{
return somemember*100;
}
virtual void func2;
};
class derived_functions2
{
virtual void func1;
virtual void func2;
};
};
class Base
{
public:
virtual void func1();
virtual ~Base(){}
};
struct Impl1 : Base
{
void func1() override {}
};
struct Impl2 : Base
{
void func1() override {}
};
struct Derived : Base
{
Derived(std::unique_ptr<Base> implementation) :
impl(std::move(implementation))
{}
void func1() override { impl->func1(); }
void changeImpl(std::unique_ptr<Base> implementation)
{
impl = std::move(implementation);
}
private:
std::unique_ptr<Base> impl;
};
Not the way you did. But you can make both the inner class derived_functionsX to be themseves public: Base, than have your main Derived to contain a std::unique_ptr<Base> ptryou can set to new derived_functions1 or new derived_functions2
and implement in Derived func1 and func2 to call ptr->func1() and ptr->func2().
For all that to work properly, Base must also have a virtual ~Base() {} otherwise no proper deletion can be done.
In this example, it won't compile, since derived_function1 and derived_functions2 aren't inheriting from Base.
But you could have something like this:
class Base
{
virtual void func1();
virtual void func2();
};
class Wrapper {
public:
Wrapper(int arg)
{
switch(arg)
{
case 1:
b = new derived_functions1;
break;
case 2:
b = new derived_functions2;
break;
default:
cout << "bad value of arg" << arg << endl;
exit(1);
}
}
~Wrapper()
{
delete b;
}
Base* GetClass()
{
return b;
}
private:
Base *b;
class derived_functions1: public Base
{
virtual void func1();
virtual void func2();
};
class derived_functions2: public Base
{
virtual void func1();
virtual void func2();
};
};
Short answer: No. A class can override inherited virtual functions only once.
However, there is a design pattern that exchanges function's behavior on the fly, called Strategy Pattern. In short: the class that has exchangeable behavior has a pointer to a Strategy base class that defines the interface for that behavior. It is populated with concrete Strategy classes. The function that has different behavior just delegates its calls to the Strategy pointer. Here's an example, tailored to your question:
class Base {
public:
virtual void func1() = 0;
virtual void func2() = 0;
virtual ~Base(){}
};
#include <iostream>
#include <memory>
class Derived : public Base
{
struct F1Strategy {
virtual void f1Impl() = 0;
virtual ~F1Strategy() {}
};
struct Impl1 : F1Strategy {
void f1Impl() override { std::cout << "one!\n"; }
};
struct Impl2 : F1Strategy {
void f1Impl() override { std::cout << "two?\n"; }
};
std::unique_ptr<F1Strategy> f1Strategy;
public:
Derived()
: f1Strategy(new Impl1())
{}
void func1() override { f1Strategy->f1Impl(); }
void func2() override {
static std::unique_ptr<F1Strategy> otherStrategy(new Impl2());
f1Strategy.swap(otherStrategy);
}
};
int main() {
std::unique_ptr<Base> pb(new Derived());
pb->func1(); // ==> one!
pb->func2(); //swap
pb->func1(); // ==> two?
pb->func1(); // ==> two?
pb->func2(); //swap
pb->func1(); // ==> one!
}
See it in action: http://ideone.com/zk3UTI