Can you set a weak_ptr<> in a ctor? - c++

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.

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.

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

C++: Exposing pointers to class with managed memory

I have the following setup:
class Foo {
public:
Foo() {}
vector<BigObject*> mPointers;
};
class Bar {
public:
Foo *exposeSomeFoo() { return &mFoos[42]; }
private:
vector<Foo> mFoos;
vector<BigObject> mMemoryManaged;
};
I'm basically trying to make sure that at no point in my code will someone accidentally use a Foo for which the Bar it was exposed from has gone out of scope.
But this is obviously problematic. If I expose pointers to Foo like above, they become invalid once Bar goes out of scope. If I instead use Foo exposeSomeFoo(), the mPointers will become invalid once Bar goes out of scope, too - and returning copies seems like a bad idea if mPointers has a lot of elements!
I've tried solving this by making a private copy constructor:
class Foo {
public:
Foo() {}
vector<BigObject*> mPointers;
private:
Foo(const Foo&);
};
But then I get errors when I try to insert a Foo into mFoos from within Bar.
There must be a paradigm that allows full memory safety while still allowing me to expose functionality like this. How can I expose, to code elsewhere, a composite object from Bar whose memory is managed specifically by Bar or at least in the compilation unit itself?
If you want to make sure that all of your objects can share resources, such that the resource is alive as long as all of the objects are, just use std::shared_ptr everywhere:
class Foo {
public:
Foo() {}
vector<shared_ptr<BigObject>> mPointers;
};
class Bar {
public:
shared_ptr<Foo> exposeSomeFoo() { return mFoos[42]; }
private:
vector<shared_ptr<Foo>> mFoos;
vector<shared_ptr<BigObject>> mMemoryManaged;
};
That way, a caller can hold onto bar.exposeSomeFoo() without worry - the caller now shares ownsership of it, sot his will be perfectly safe.
Actually, I ended up doing something like this:
class Foo {
public:
Foo(shared_ptr<vector<BigObject> > bigObjects) : mBigObjects(bigObjects) {
}
private:
vector<BigObject*> mPointers;
shared_ptr<vector<BigObject> > mBigObjects;
};
class Bar {
public:
Bar() {
mBigObjects = shared_ptr<vector<BigObject> >(new vector<BigObject>);
for (int i = 0; i < 100; i++)
mBigObjects->push_back(BigObject());
for (int i = 0; i < 100; i++)
mFoos.push_back(Foo(mBigObjects));
}
Foo exposeSomeFoo() { return mFoos[42]; }
private:
shared_ptr<vector<BigObject> > mBigObjects;
vector<Foo> mFoos;
};
I think this is the behavior I want: only when all instances of both Foo and Bar are destroyed, is the vector with BigObjects actually destroyed. Can someone double-check that this is safe and good practice? Thanks!

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

How to design a class where the user/caller has options to provide a custom behavior using a custom class

I encounters a problem where I want to have a class in which its behavior can be customized by another class, for example, Foo's constructor accepts a parameter of some type of class:
class Bar { //The default class that define behavior
};
template <typename T = Bar>
class Foo {
public:
Foo(T* t = 0) t_(t) {
if (t_ == 0) t_ = new T();
}
~Foo() {
delete t_;
}
}
Now if someone use Foo in a client code:
Foo foo;
Everything is fine. But, if we want to supply the custom class:
class Bar1 { };
Foo<Bar1> foo(new Bar1()); // This is OK
Bar1 b;
Foo<Bar1> foo(&b); // Error, b is not dynamically allocated
Is there any design pattern I can use to prevent this kind of mistakes? Or, is there any techniques or semantics where the user of Foo class can choose/specify who owns the bar object? So for example, the above Foo destructor can be like this:
~Foo() {
if (t_ is owned by this object) delete t_;
}
Bar or Bar1 or any class passed as t in Foo(T* t) might be a big object, so if it is possible I rather not to pass it by value.
Update:
What I have in mind is for the user to be able to do something like:
Foo foo(new Bar(1, 2, etc..));
//or this:
Bar bar(1, 2, etc..);
Foo foo(bar);
But if bar is a big object (for example, contains an array), then it would be inefficient to pass bar by value. The only way is to have bar passed by reference or pointer, but I also want the user to be able to use bar with parameterized constructor, and hence my confusion began.
Regarding to the auto variable scope, it would be safe if a user do something like:
int main() {
Bar1 bar1(1,2,3);
Foo foo(&bar1);
return 0;
}
As long as Foo does not delete bar1.
You can't detect the difference between stack and heap allocation (the standard doesn't even mention a stack), but that's not the issue here.
Foo should not be deleting things that it does not own. If it wants a copy for itself then it should just make a copy:
template <class T = Bar>
class Foo
{
T t_;
public:
Foo() {}
Foo(const T& t) : t_(t) {}
};
Or if you need it to be a pointer:
template <class T = Bar>
class Foo
{
T* t_;
public:
Foo() : t_(new T()) {}
Foo(const T& t) : t_(new T(t)) {}
};
You can't just go around deleting things that people give you, and that's regardless of whether you know if it's stack or heap allocated. What if your Foo goes and deletes it but the calling code still wants to use it? Or what if that same object is passed into two of your Foo objects and they both delete it?
Your option is either to make a copy, or not delete it.
An alternative to doing the copy would be to mark whether you are using your own or someone else's:
template <class T = Bar>
class Foo
{
T* t_;
bool owned;
public:
Foo() : t_(new T()), owned(true) {}
Foo(T* t) : t_(t), owned(false) {}
~Foo() { if (owned) delete t_; }
};
In case you are wondering, t is passed by const-ref in my previous solutions, not by value, so there is no excessive expense, although there could be an expense in the copying.
Use a smart pointer and you won't have to worry about memory management. If you really have to, I guess you should have the user of your class handle the memory they pass in, your class should be only responsible for deleting the objects that it created.
You have to consider if you really need to use pointers. A simple design like this one:
template <typename T = Bar>
class Foo1 {
T t_;
public:
Foo1() {
}
Foo1(const T& t) : t_(t) {
}
};
might be all you need. There's nothing wrong with using it like this:
int main() {
Bar1 bar1(1,2,3);
Foo1 foo(bar1); // specify custom behavior
Foo1 foooo; // get default behavior
return 0;
}
If you really need pointers, Dan provided a good answer using std::auto_ptr<>. You can guarantee you always have an object created with something like:
template <typename T = Bar>
class Foo2 {
std::auto_ptr<T> t_;
public:
Foo2() : t_(std::auto_ptr<T>(new T)) { }
Foo2(std::auto_ptr<T> t) : t_(t) {
if (t_.get() == 0) t_ = std::auto_ptr<T>(new T);
}
};
Then you can call it like this:
std::auto_ptr<Bar1> s(new Bar1());
Foo2<Bar1> foo(s);
Foo2<Bar1> foooo;
As for the user passing the address of a stack object to a smart pointer, that's really the user's fault for doing something wrong. The program will crash as soon as the auto_ptr tries to delete the object.
Short answer, No.
For any arbitrary type T to be used such as Bar1 then you have to simply accept that your class's users may write code that explodes.
However if you only construct the instance of type T when you construct the class, instad of taking a pointer to an instance you could in Foo's code construct the instance of Bar1 using a Create function. But then you can't pass arguments to the constructor.
class Bar
{
public: static Bar * Create()
}
template <typename T>
class Foo
{
public: static Foo<T>* Create() { return new Foo<T>(T::Create()); }
}
I can in now way endorse this for anything but pure fun, but here is a class that tests where it was allocated:
class AllocTester {
public:
bool on_stack() {
AllocTester outer;
return on_stack_check(&outer);
}
private:
bool on_stack_check(AllocTester *outer) {
AllocTester inner;
return (outer < &inner) == (this < &inner);
}
};
This won't work with multithreading, static variables or unusual architectures. So if you try to use this for any "real" coding you will just break you application. Only look at it as curiosity, in real life the caller of your class should be responsible to handle the allocated memory correctly.
Usually if there is a function that allocates memory, there should be a corresponding function that frees it again. If the class takes ownership of the passed pointer this should be made explicitly clear. Maybe even using auto_ptr would be a good idea since it explicitly transfers ownership of the pointer to the constructor.
To clarify my comments in Poita_'s answer:
template <typename T = Bar>
class Foo {
T& t_;
std::auto_ptr<T> pT_;
public:
Foo(T& t) : t_(t) {
}
Foo(std::auto_ptr<T> pT) : pT_(pT), t_(*pT) {
}
T& getT() const {
T* pT = pT_.get();
if (pT != NULL)
return *pT;
return t_;
}
};
You can then use it as follows:
std::auto_ptr<Bar> pBar(new Bar());
Foo<Bar> foo0(pBar);
Bar& b0 = foo0.getT();
Bar b;
Foo<Bar> foo1(b);
Bar& b1 = foo1.getT();
As this code shows, you should (almost) always place the result of new into some object which manages the memory. std::auto_ptr<> will pass ownership of the pointer to Foo. Alternatively, you could pass the pointer directly in the constructor, but that makes it easier to call Foo(&bar).