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

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.

Related

Why create an object with a static shared_ptr returning member?

I've seen such pattern around and am curious what's the benefit of such pattern. What's the difference between creating an object with static and with pure constructor?
class Foo {
static std::shared_ptr<Foo> create(); // why expose this function?
Foo(folly::observer::Observe<Config> config);
};
One reason to do this would be to force all instances of the object to be owned by shared_ptr's (instead of statically constructed). This is especially helpful when using shared_from_this().
For example, consider the following program:
#include <memory>
class Foo;
void globalFunc(const std::shared_ptr<Foo> &) {
// do something with the ptr
}
class Foo
: public std::enable_shared_from_this<Foo>
{
public:
Foo() {}
void classMemberFunc()
{
globalFunc(shared_from_this());
}
};
In this program, a Foo object can access/pass a shared pointer to itself, similar to how it can access/pass the this pointer. When classMemberFunc() is called on an object of Foo, globalFunc receives a reference to a shared_ptr the holds Foo.
However, with this design, Foo needs to be owned by a shared_ptr in the first place.
int main()
{
// valid use
auto sptr = std::make_shared<Foo>();
sptr->classMemberFunc();
}
If a Foo object isn't owned by a shared_ptr, shared_from_this() has undefined behavior before C++17 and a runtime error in C++17.
int main()
{
// invalid use - undefined behavior or runtime error
Foo nonPtrFoo;
nonPtrFoo.classMemberFunc();
}
We would like to prevent this at compile time. We can do this using the static "create" method and a private constructor.
class Foo
: public std::enable_shared_from_this<Foo>
{
public:
static std::shared_ptr<Foo> create() // force shared_ptr use
{
return std::shared_ptr<Foo>(new Foo);
}
void classMemberFunc()
{
globalFunc(shared_from_this());
}
private:
Foo() {} // prevent direct construction
};
int main()
{
// valid use
auto sptr = Foo::create();
sptr->classMemberFunc();
// invalid use - now compile error
Foo nonPtrFoo;
nonPtrFoo.classMemberFunc();
}

How to store templated objects of different type in container?

Assuming I have a vector (or list or whatever container might be more suitable here) that I would like to store multiple objects (or pointers) of a templated type in:
std::vector<MyClass<double>> v;
// std::vector<MyClass<double> *> v;
Unfortunately, I want to store different templated objects in this container (and I need to access them ideally at constant time).
My first intuition was to create some sort of WrapperClass around MyClass that would internally manage any MyClass as a member variable, but it's not clear to me how I could pass along the appropriate type through to MyClass:
#include <iostream>
#include <string>
#include <stdlib.h>
#include <vector>
using namespace std;
template<typename T>
class MyClass
{
public:
MyClass() {}
~MyClass() {}
};
// templating this of course works, but it doesn't solve my problem
template<typename T>
class WrapperClass
{
public:
WrapperClass()
{
m_object = MyClass<T>();
}
~WrapperClass() { }
private:
MyClass<T> m_object;
};
int main()
{
WrapperClass<bool> tmp = WrapperClass<bool>();
std::vector<WrapperClass<bool> *> v;
return 0;
}
So is there (A) a different container than vector that I could be using for this problem or (B) a way to select the type of MyClass in WrapperClass inside the constructor? I was thinking of something along the lines of:
class WrapperClass2
{
public:
WrapperClass2(unsigned int typeId)
{
switch (typeId)
{
case 0: m_object = new MyClass<bool>();
case 1: m_object = new MyClass<int>();
case 2: m_object = new MyClass<float>();
default: m_object = new MyClass<double>();
}
}
~WrapperClass2()
{
delete m_object;
}
private:
MyClass * m_object;
};
Another idea may be to have some parent AbstractType that I would be using in the vector, but I'm not sure how that would help with the templated type problem.
Different instantiations of a class template are completely unrelated types, so you cannot have a container that directly stores them.
You have a few options:
Keep a collection of pointers to some base class that your class template inherits from:
class Base
{
virtual ~Base {}
virtual void someMethod() const = 0;
};
template <typename T>
class MyClass : public Base
{
void someMethod() const
{
// stuff
}
};
int main()
{
std::vector<std::unique_ptr<Base>> objs;
objs.push_back(std::make_unique<MyClass<int>>());
objs.push_back(std::make_unique<MyClass<std::string>>());
for (auto& i : objs) {
i->someMethod();
}
}
This is a fairly simple approach, but it incurs a bit of runtime overhead with dynamic allocation and RTTI. Note also that someMethod can't return T, since it's a method on a parent class that doesn't know what T is.
Use some sort of type-erased wrapper like boost::any (or the forthcoming std::any in C++17).
#include <any>
#include <string>
#include <vector>
template <typename T>
class MyClass {
public:
T someMethod() const {
// stuff
return {};
}
};
void someFunctionThatTakesInt(int i) {}
void someFunctionThatTakesString(std::string s) {}
int main() {
std::vector<std::any> objs;
objs.push_back(MyClass<int>());
objs.push_back(MyClass<std::string>());
for (const auto& i : objs) {
if (i.type() == typeid(MyClass<int>)) {
auto& mc = std::any_cast<const MyClass<int>&>(i);
someFunctionThatTakesInt(mc.someMethod());
} else if (i.type() == typeid(MyClass<std::string>)) {
auto& mc = std::any_cast<const MyClass<std::string>&>(i);
someFunctionThatTakesString(mc.someMethod());
}
}
}
This approach means that you can have someMethod return T, but makes it much harder to handle retrieving objects from the vector because you have to figure out what type they are before you can do anything with them (you're essentially rolling your own RTTI).
Don't.
Rethink why you need this in the first place. Maybe another approach could work better. Maybe something with callbacks or visitors. I don't know your objective here, so I can't really say what's appropriate.
Can you do a base class and have all other classes inherit from the base class.
And you can make a list that holds a list of base class elements.
Now this is more of a pseudo example, but I hope this way would solve your problem.
Example:
class Base:
{
}
class whatever:Base
{
}
class whatever2:Base
int main()
{
list<whatever> object1;
list<whatever2> object2;
list<list<Base>> mainObj;
mainObj.push_back(object1);
mainObj.push_back(object2);
}
Now if the problem is to just have different datatypes than abstract datatypes in some container. Can't you have a Singly Link List, and have your Node generic.
Example:
template<typenameT>
struct Node
{
T data;
Node* next;
}
class LinkList
{
//Your code:
}

Autoregister Objects to list stores shared pointers

I would like to implement a base object, which can autoregister itself into a singleton object list. I would store shared pointers pointing to these objects in the list. The registration would be good to happen either in the constructor or a separate initialisation function set(). My problem is that the object does not know it's shared pointer. How can I solve this problem?
The object:
class Object
{
public:
Object() {}
virtual ~Object() {}
void set()
{
// register object, how?
}
void unset() {
// unregister object, how?
}
};
The object list:
#include <memory>
#include <list>
class ObjectPool
{
public:
void unregisterObject(std::shared_ptr<Object> objPtr) {
objPtrList.remove(objPtr);
}
void registerObject(std::shared_ptr<Object> objPtr) {
objPtrList.push_back(objPtr);
}
private:
std::list<std::shared_ptr<Object> > objPtrList;
};
Usage:
int main()
{
auto objPtr = std::make_shared<Object>();
objPtr->set();
objPtr->unset();
}
I would not want to use the register/unregister methods of the container singleton directly, because
I want to hide this registering mechanism from user codes, and
set/unset functions do additional staff besides registering
I suspect that this problem may come from inadequate design so I'm interested in solutions with completely different designs also, if they can used for the same purpose.
Update: Solution
Deriving Object from std::enable_shared_from_this:
class Object : public std::enable_shared_from_this<Object>
{
public:
Object() {}
virtual ~Object() {}
void set()
{
ObjectPool.registerObject(shared_from_this());
}
void unset() {
ObjectPool.unregisterObject(shared_from_this());
}
};
Derive you Object from std::enable_shared_from_this.

C++ Non-destructible classes

Is there any way in C++ to create class within a function, and then prevent it from destructing?
like
class someclass {
public:
int x;
someclass() { x = 0; };
}
someclass::x;
and then somewhere
someclass * somefunction()
{
someclass somecl ();
return &somecl;
}
So we call function 'somefunction' and get pointer to class for later using. I need it to exist as long as program runs/it destructed by other function. Is there any way to do it without storing it inside arrays or vectors?
I'm not sure if what you're looking for is a way to define an object once and only once, returning a pointer to the same object each time, or to create a factory function that returns the a newly constructed object each time. If it's the second, look at previous answers. If it's the first, check out static variables. As an example, you could write
someclass * somefunction()
{
static someclass somecl ();
return &somecl;
}
This ensures that somecl is only defined once, when the function is initially run and that it will be alive until your program exits. (For a more precise description of the order of cleanup for static variables, see here.)
Yes, you have to allocate the memory on the heap and then delete the memory when you are done.
someclass * somefunction()
{
return new someclass();
}
int main()
{
someclass * myclass = somefunction();
// do stuff with myclass
delete myclass;
return 0;
}
someclass * somefunction()
{
return new somecl ();
}
You were very close :)
You could create it on the heap rather than the stack:
someclass * somefunction()
{
return new someclass();
}
You may also want to consider returning it in a smart pointer, to explicitly transfer ownership and control its lifetime.
I'm not exactly sure what you are driving at, I can imagine two different use cases where you would want to make a class indestructible.
Case 1: Singleton
The idiomatic way to do this, is to use a static instance of the class that's declared within an accessor function:
class Foo {
public:
static Foo& globalFoo();
private:
Foo() {};
~Foo() {};
};
Foo& Foo::globalFoo() {
static Foo myFoo;
return myFoo;
}
int main() {
Foo& myFoo = Foo::globalFoo();
}
That way, it is impossible for other code to either construct or destruct any instance of Foo, it can only use the one instance that's provided by the globalFoo() function.
Case 2: Wrapped allocation/deallocation
If you just want to force allocation/deallocation to happen via certain static functions, you only need to make both the constructor and the destructor private (just as in the singleton case), and add static functions to the interface for allocation/deallocation:
class Foo {
public:
static Foo* makeFoo();
static void destroyFoo(Foo* aFoo);
private:
Foo() {};
~Foo() {};
};
Foo* Foo::makeFoo() {
return new Foo();
}
void Foo::destroyFoo(Foo* aFoo) {
delete aFoo;
}
int main() {
Foo* myFoo = Foo::makeFoo();
Foo::destroyFoo(myFoo);
}

Can you set a weak_ptr<> in a ctor?

The following code fails to compile in Visual C++ 11 with this error:
1>c:\users\tony\documents\visual studio 11\projects\cpp11_ex1\cpp11_ex1\main.cpp(52): error C2440: '' : cannot convert from 'Foo *const ' to 'std::weak_ptr<_Ty>'
#include <stdio.h>
#include <memory>
using namespace std;
class Foo;
class Bar
{
public:
Bar( weak_ptr<Foo> foo ) : _foo(foo) { printf("Bar(%p)\n",this); }
~Bar() { printf("~Bar(%p)\n",this); }
private:
weak_ptr<Foo> _foo;
};
class Foo
{
public:
Foo() : _bar() { _bar = make_shared<Bar>( weak_ptr<Foo>(this) ); printf("Foo(%p)\n",this); }
~Foo() { printf("~Foo(%p)\n",this); }
private:
shared_ptr<Bar> _bar;
};
int main( int argc, char* argv[] )
{
shared_ptr<Foo> instance = make_shared<Foo>();
return 0;
}
It seems that I can't create a weak_ptr from a raw this pointer. This causes an interesting series of problems.
Since I am attempting this in Foo's ctor, Foo's reference count is 0 (i.e. the make_shared<> in main hasn't returned yet).
I've discovered that I can create weak_ptrs from shared_ptrs... But if I change Bar ctor to take a shared_ptr, I the act of calling Bar's constructor ends up destroying Foo! (Since Foo's reference count is still 0, creating (and then destroying) a shared_ptr to Foo via a call to Bar's ctor ).
All I really want to do is create Foo, have Foo create and own a Bar, but have Bar have a weak reference back to Foo. I really don't want to be forced into 2 part initialization here!
boost::weak_ptr<T> is for storing, not for using.
You want to pass boost::shared_ptr objects, and then store them in the boost::weak_ptr objects (usually private).
struct Foo {
Foo(const boost::shared_ptr<int> &data) : weak_data(data) {}
boost::shared_ptr<int> getData() {
boost::shared_ptr<int> data = weak_data.lock();
if (!data)
throw std::runtime_error("data is no longer valid");
return data;
}
private:
boost::weak_ptr<int> weak_data;
};
Whether you throw or pass back and empty shared_ptr<T> is up to you. If you cannot lock the object though, you shouldn't be passing it around anymore. It really isn't valid at that point.
That being said, you may want to refrain from creating a shared pointer in that manner. It isn't clear from your example if you need this design. If you can redesign it in a way like Mooing Duck suggested you will be better off, in all honesty.
From similar experiences when I needed circular dependencies like this, it probably is not a simple construction scenario. I would look at a two part constructor (static named constructor, or builder perhaps) to manage creating the two objects and ensuring that their references are valid.
Here is a quick example of a simple named constructor.
class Foo;
// Likely that this should be a child class of Foo
class Bar {
private:
friend class Foo;
Bar(const boost::shared_ptr<Foo> &foo) : weak_foo(foo) {}
weak_ptr<Foo> weak_foo;
};
class Foo {
public:
static boost::shared_ptr<Foo> CreateFoo() {
boost::shared_ptr<Foo> foo = boost::shared_ptr<Foo>(new Foo);
foo.bar = boost::make_shared<Bar>(foo);
return foo;
}
private:
Foo() {}
boost::shared_ptr<Bar> bar;
};
Here you control the invariant that your foo and bar variables are created correctly.
Since Foo will be pointed at by a shared_ptr, and Bar will always be owned by a shared_pointer of Bar, then if Bar exists, Foo exists. Ergo, you don't need a smart pointer in Bar. (If I understand the problem correctly)
#include <stdio.h>
#include <memory>
using namespace std;
class Foo;
class Bar
{
public:
Bar( Foo* foo ) : _foo(foo) { printf("Bar(%p)\n",this); }
~Bar() { printf("~Bar(%p)\n",this); }
private:
Foo* _foo;
};
class Foo
{
public:
Foo() : _bar(new Bar(this)) { printf("Foo(%p)\n",this); }
~Foo() { printf("~Foo(%p)\n",this); }
private:
shared_ptr<Bar> _bar;
};
int main( int argc, char* argv[] )
{
shared_ptr<Foo> instance = make_shared<Foo>();
return 0;
}
It is not possible to have a weak pointer in the absence of strong pointers to the same object, by definition. When the last strong pointer goes away, all the weak pointers turn null. That's all the weak pointers do.
Write your own function that returns a shared ptr to Foo (a Foo factory), and initialize the weak ptr in Bar from that pointer.