C++11 dependency injection in constructor with reference - c++

Consider following code:
#include <stdio.h>
#include <memory>
class Sub{};
class SubImpl : public Sub {};
class A{
public:
A(Sub & sub) : sub(sub){}
void doSomething(){
// ...
};
private:
Sub & sub;
};
std::unique_ptr<A> factory(){
SubImpl sub;
return std::unique_ptr<A>(new A(sub));
}
int main(){
auto a = factory();
a->doSomething();
}
This code have problem - Sub object lifetime is not same as A object, and A::sub reference is dangled.
In order to fix this, I can do:
pass by value
pass by const reference
use unique_ptr / shared_ptr or to use raw pointer
Is there any other way I can fix this?

Use unique_ptr if the object sub is used solely to create only one A object. Use shared_ptr otherwise.
class Sub{};
class SubImpl : public Sub {};
class A{
public:
A(std::unique_ptr &&sub) : sub(std::move(sub)){}
void doSomething(){
// ...
};
private:
std::unique_ptr sub;
};
std::unique_ptr<A> factory(){
auto sub = std::make_unique<SubImpl>();;
return std::make_unique<A>(std::move(sub));
}
int main(){
auto a = factory();
a->doSomething();
}

It seems you have two choices, either the lifetime of SubImpl is controlled by A in which case I see no alternative to using a pointer, preferably a unique_ptr, like bolov has shown. And I don't think there is anything particularly wrong with that.
Or the lifetime of SubImpl is controlled by something outside of A in which case you can use references.
For example, you could change the factory so that it is an object that owns the SubImpl. Here is a simplistic example:
// definitions of Sub, SubImpl and A as before...
class SubOwner {
SubImpl sub;
public:
A createA() const {
return A(sub);
}
};
int main(){
SubOwner so;
auto a = so.createA();
a.doSomething();
}
That's fine if you only want one SubImpl but it is possible that you want to use your factory to create many As and each A should have a reference to a different SubImpl. In which case you could have an object that owns a collection of SubImpl:
class SubOwner {
// Using deque instead of vector to avoid reference invalidation.
// Could use vector if you knew how many SubImpl you need up front.
std::deque<SubImpl> subs;
public:
A createA() const {
subs.emplace_back();
return A(subs.back());
}
};
int main(){
SubOwner so;
auto a1 = so.createA();
auto a2 = so.createA();
a1.doSomething();
a2.doSomething();
}
Providing SubOwner and A are themselves owned by the same object or local to the same scope then you can guarantee that the lifetime of SubImpl will be the same as A.

Related

How to store pointers to objects that class doesn't own?

I am trying to code two classes FooFactory and Foo. FooFactory initializes an object ToolBox in the constructor and stores it in a unique_ptr as I want that to be cleaned after the factory is destructed. All the instances of Foo should be able to use ToolBox so I am passing ptr to ToolBox object in the constructor of Foo and storing it as bare ptr.
I am new to c++ development so, my questions in the light of general suggestion I heard :
avoid raw pointers when possible
Is the usage of bare ptr to store the tool_box object that Foo doesn't own fine in this case? or Can I do better using smart_ptr?
Is the pattern of passing the ptr to ToolBox from the FooFactory class to every new object the correct or is there something better I can do?
Pseudo-code for my classes:
class FooFactory {
public:
FooFactory() {
tool_box_.reset(new ToolBox());
}
std::unique_ptr<Foo> NewFoo() {
std::unique_ptr<Foo> foo(new Foo(tool_box_.get());
return foo;
}
std::unique_ptr<ToolBox> tool_box_;
}
class Foo {
public:
Foo(ToolBox* tool_box) {
tool_box_ = tool_box;
}
private:
// Not Owned
ToolBox* tool_box;
}
A factory would normally never control the lifetime of an object. It should hand out an appropriate pointer, preferably a std::unique_ptr and the caller determines it's lifetime.
#include <string>
#include <iostream>
#include <memory>
class Box
{
public:
Box() {}
};
class Foo
{
public:
Foo(std::shared_ptr<Box> &box)
: m_box(box)
{
}
virtual ~Foo(){}
void print()
{
std::cout << "Hello World" << std::endl;
}
protected:
Box *getBox()
{
return m_box.get();
}
private:
std::shared_ptr<Box> m_box;
};
class FooFactory
{
public:
FooFactory()
{
m_box = std:make_shared<Box>();
}
std::unique_ptr<Foo> CreateFoo()
{
return std::make_unique<Foo>(m_box);
}
private:
std::shared_ptr<Box> m_box;
};
int main()
{
FooFactory factory;
std::unique_ptr<Foo> foo = factory.CreateFoo();
foo->print();
return 0;
}
One way to store a non-owning "pointer" to an object (while coupling the class with that object) would be to store a reference (or perhaps a const reference) instead of a pointer.
In my experience, the constraint of needing to initialize the class with that reference helps hierarchical design and simplifies lifetime management.

C++ Function with side-effect used at file scope, accesses singleton

I've written a class with the following static method:
MyMap& Manager::GetMap( void )
{
static MyMap* factories = new MyMap();
return ( *factories );
}
Where "MyMap" is a typedef for:
unordered_map<string, function<Base* ( Dependency& d )>>
There are also a variety of types derived from Base e.g.
class Derived1 : public Base
{
public:
Derived1( Dependency& d );
};
Consider the following usage.
I define the following in an implementation file for Derived1:
#include "Derived1.h"
#include "Manager.h"
int RegisterDerived1( void )
{
Manager::GetMap()["Test"] = []( Dependency& d ){ return new Derived1( d ); };
return 0;
}
int Reg = RegisterDerived1();
You can't call functions at file scope, but you can assign the return value of a function to a global variable even if that function has side effects. Hence, by the time that "Manager" is in use the "MyMap" will contain string/function pairs for various derived types of "Base" (so far). The intent is that new derived types of "Base" register themselves with "Manager", able to construct instances of that type and select which type based on a name.
I'm wondering if this represents safe behaviour and/or if there are alternative implementations to get the desired effect?
I've been made aware of this article that proposes a generic registration object that takes the above pair in its constructor and does the registering, a static instance of which is then defined for each class to be registered.
http://accu.org/index.php/journals/597
The principle is fine.
A few things you may want to consider:
returning raw pointers is a bad idea - use unique_ptr instead.
Did you really want the Dependency& reference to be non-const?
Hide the internal implementation. There's no need for users to know (or care) that it's an unordered_map.
A slightly modified version with inline comments for you to consider:
#include <functional>
#include <unordered_map>
#include <memory>
#include <string>
struct Base
{
virtual ~Base() = default;
};
struct Dependency
{
};
struct Manager
{
// I notice that Depdendency& is not const. Was that what you wanted?
using factory_function = std::function<std::unique_ptr<Base> ( Dependency& d )>;
// public registration function hides internal implementation of map
static bool register_function(const std::string ident, factory_function f)
{
return GetMap().emplace(std::move(ident), std::move(f)).second;
}
// public create function hides internal implementation of map
// returns a unique_ptr - much better!
static std::unique_ptr<Base> create(const std::string& ident, Dependency& d)
{
// this will throw an exception if the factory does not exist.
// another implementation could substitute a known version of Base,
// for example. But now it's under your control and the user does
// not have to think about it.
return GetMap().at(ident)(d);
}
private:
using MyMap = std::unordered_map<std::string, factory_function>;
// private map implementation. In future we may want to add a mutex
// (in case the map can be dynamically updated?)
// so let's encapsulate
static MyMap& GetMap()
{
// no need for new here. Static variables are cleanly destructed at
// the end of the program, and initialised the first time the code
// flows over them.
static MyMap _map;
return _map;
}
};
struct Derived1 : Base
{
Derived1(Dependency&) {}
};
// now we don't need to care about Manager's implementation.
// this is better - we are decoupled.
bool derived1_registered = Manager::register_function("Derived1",
[](Dependency& d)
{
return std::make_unique<Derived1>(d);
});
int main()
{
Dependency d;
auto p = Manager::create("Derived1", d);
return 0;
}

Can I make a variable _const from now on_?

I'm using a library that has a class with an init function distinct from its constructor. Every time I make a new instance I need to call, for example:
MyClass a;
a.init();
Since init is not const, this prevents me from creating const instances (I can't write const MyClass a). Is there some way to call init and then declare from "here on out" (I guess for the remainder of the scope) my variable is const?
This works, but relies on not touching the original variable:
MyClass dont_touch;
dont_touch.init();
const MyClass & a = dont_touch;
If you're using C++11 you could use a lambda function
const MyClass ConstantVal = []{
MyClass a;
a.init();
return a;
}();
This allows you to keep the initialization in place while never giving outside access to the mutable object.
see also:
http://herbsutter.com/2013/04/05/complex-initialization-for-a-const-variable/
You can create a wrapper class and use that instead.
If MyClass has a virtual destructor you can feel safe deriving from it like this:
class WrapperClass : public MyClass
{
public:
WrapperClass()
{
init(); // Let's hope this function doesn't throw
}
};
Or write a class that contains the MyClass instance
class WrapperClass
{
public:
WrapperClass()
{
m_myClass.init(); // Let's hope this function doesn't throw
}
operator MyClass&() {return m_myClass;}
operator const MyClass&() const {return m_myClass;}
private:
MyClass m_myClass;
};
Or write a template to solve this general problem using one of the two solutions above: eg.
template <class T> class WrapperClass : public T
{
public:
WrapperClass()
{
T::init();
}
};
typedef WrapperClass<MyClass> WrapperClass;
Create a function that wraps the first two lines and gives you an object that is ready to go.
MyClass makeMyClass()
{
MyClass a;
a.init();
return a;
}
// Now you can construct a const object or non-const object.
const MyClass a = makeMyClass();
MyClass b = makeMyClass();
Update
Using makeMyClass() involves construction and destruction of a temporary object everytime the function is called. If that becomes a significant cost, makeMyClass() can be altered to:
MyClass const& makeMyClass()
{
static bool inited = false;
static MyClass a;
if ( !inited )
{
inited = true;
a.init();
}
return a;
}
It's usage, as described earlier, will continue to work. In addition, once can also do this:
const MyClass& c = makeMyClass();
You can actually do it quite simply, even without C++11 and lambdas:
const MyClass a;
{
MyClass _a;
_a.init();
std::swap(const_cast<MyClass&>(a), _a);
}
The use of const_cast is admittedly a bit of a hack, but it won't break anything as const is quite a weak specifier. At the same time, it is quite efficient, as the MyClass object is only swapped, not copied (most reasonable expensive-to-copy objects should provide a swap function and inject an overload of std::swap).
Without the cast, it would require a helper:
struct Construct_Init {
operator MyClass() const
{
MyClass a;
a.init();
return a;
}
};
const MyClass a = Construct_Init();
This can be like this in a function (the Construct_Init structure needs not be declared at namespace scope), but it is a bit longer. The copy of the object may or may not be optimized away using copy elision.
Note that in both cases, the return value of init() is lost. If it returns a boolean where true is success and false is failure, it is better to:
if(!a.init())
throw std::runtime_error("MyClass init failed");
Or just make sure to handle the errors appropriately.

How to pass a linc to class function and call it?

So I have a class like
class mySafeData
{
public:
void Set( int i )
{
myMutex.lock();
myData = i;
myMutex.unlock();
}
void Get( int& i)
{
myMutex.lock();
i = myData;
myMutex.unlock();
}
private:
int myData;
boost::mutex myMutex;
};
its instance is running. Lets call instance A. I want to create a new class that would take as a start up argument some kind of link to Getter from A and would be capable to somehow save link to thet getter for calling it inside its private methods vhen needed. how to do such thing?
Sounds like you want something like this:
class myOtherData
{
public:
myOtherData(mySafeData& dataSource) :
myDataSource(&dataSource)
{}
private:
// note that if you take the advice in the comments,
// you don't need this wrapper function at all,
// it's simple just to call myDataSource.Get()
int GetData()
{
int result;
myDataSource.Get(result);
return result;
}
mySafeData* myDataSource;
};
mySafeData a;
myOtherData b(a);
// b uses a as its data source (make sure it lives as long!)
I'm not sure what you mean by linc/link. Are you asking for anything more than this pattern?
class Foo {
public:
Foo(mySafeData& d) : data(d) {}
int someFunction() {
int i;
data.get(i);
return i;
}
private:
mySafeData& data;
};
...
Foo f(a);
What's wrong with pointers? Smart, Shared, Scoped... I'll use standard pointers for now.
class B
{
public:
B(mySafeData* ptr) // constructor takes a memory pointer as parameter
:SafeData_ptr(ptr)
{
SafeData_ptr->foo(); // call public function from class A
}
~B() // destructor
{
}
private:
mySafeData* SafeData_ptr; // will hold the mem address of instance A when
// this class is initialized
};
Later on your code, when you have instance A ready, you would do something like this:
B b_demo(&A); // &A passes the memory address of the instantiated object
// and A::foo() will be automatically called when B is constructed.
This is probably not the smartest way to do it, but I think it illustrates the idea.

How to maintain a weak pointer to a parent in C++?

Is there a standard way of maintaining a weak pointer to a parent (which is created using a shared pointer) in a child object in C++?
Essentially, I need to implement something on the lines of the following:
Class B;
Class A
{
...
private:
B m_b;
};
Class B
{
....
public:
void SetParentPtr(const boost::shared_ptr<A>& a)
{
m_parentPtr = a;
}
private:
boost::weak_ptr<A> m_parentPtr;
};
In the above all instances of class B need to hold a weak pointer to their parent (i.e object of class A). Class A objects are instantiated using a shared_ptr. I can think of a solution that uses a null deleter. But is that a standard way of doing something like this?
What you are doing above is explicitly supported by weak_ptr and shared_ptr, what happens when you try it? To be more precise, do what you are doing, without the null deleter, and then you use the standard behaviour on the weak_ptr to convert it to a shared_ptr as needed:
boost::shared_ptr<X> it=myWeakPtr.lock();
if (it)
{
// if the conversion succeeded, then the parent instance is still alive
}
There is an implicit conversion to weak_ptr, so you can use
void SetParentPtr(boost::weak_ptr<A> a) { }
directly.
check also boost::shared_from_this so the parent can give a pointer to himself without storing a weak_ptr explicitly.
Otherwise, this seems like a normal way to have a back-pointer. Just check whether there is a real added value in using back-pointers.
I would try to do something like this:
class A
{
A(){};
public:
static boost::shared_ptr<A> Create()
{
boost::shared_ptr<A> newPtr(new A());
newPtr->m_self = newPtr;
return newPtr;
}
// ...
void CreateChild()
{
m_childPtr = B::Create(m_self);
}
private:
boost::shared_ptr<B> m_childPtr;
boost::weak_ptr<A> m_self;
};
class B
{
B(){};
public:
static boost::shared_ptr<B> Create(boost::shared_ptr<A> ptrA)
{
boost::shared_ptr<B> newPtr(new B());
newPtr->m_parentPtr = ptrA;
return newPtr;
}
boost::weak_ptr<A> m_parentPtr;
};