3

I need to register object in global list. I know I can't use make_shared_from_this in constructor - what do I use instead?

vector<shared_ptr<A> > alpha;

struct A : enable_shared_from_this<A>
{
   int x;
   A():x(9)
   {

       //alpha.push_back(shared_from_this());
       //alpha.push_back(shared_ptr<A>(this));
   }

};

1) first push back would result in crash:

ibc++abi.dylib: terminating with uncaught exception of type std::__1::bad_weak_ptr: bad_weak_ptr

2) second push back would result in segmentation fault

Piotr Skotnicki
  • 46,953
  • 7
  • 118
  • 160
Draif Kroneg
  • 743
  • 13
  • 34
  • 1
    Have you considered the use of a vector> instead? (it depends on having alpha vector holding from destruction matters or not) – marom Oct 08 '15 at 11:33

2 Answers2

3

You cannot use shared_from_this from constructor and you actually don't need shared_from_this here. You can just write something like create function.

vector<shared_ptr<A> > alpha;
// in struct A
static shared_ptr<A> create()
{
   shared_ptr<A> pointer = make_shared<A>();
   alpha.push_back(pointer);
   return pointer;
}

put constructor in private location and use any trick from How do I call ::std::make_shared on a class with only protected or private constructors?

Community
  • 1
  • 1
ForEveR
  • 55,233
  • 2
  • 119
  • 133
2

Is the global vector just meant to list all the objects in memory or do you actually delete objects from the vector. In the later case ForEveR gave a good answer. In the former case, if the code would work, none of the shared_ptr you create would get deleted until the end of the program because they are stored in a global vector. In this case just keep it simple and use old style pointers and add them at the constructor and delete in destructor. For efficiency it's better to change the vector data type. E.g.,

#include<iostream>
#include<memory>
#include<unordered_set>

class A;
std::unordered_set<A*> alpha;

class  A{
public:
  A(): x(9)
  {
    alpha.insert(this);
  }

  ~A(){
     alpha.erase(this);
  }

private:
  int x;
};

Example test:

int main(){
  std::shared_ptr<A> a= std::make_shared<A>();
  std::cout << "Number of objects: " << alpha.size() << std::endl;  
  {
    std::shared_ptr<A> a1= std::make_shared<A>();
    std::shared_ptr<A> a2= std::make_shared<A>();
    std::cout << "Number of objects: " << alpha.size() << std::endl;
  }
  std::cout << "Number of objects: " << alpha.size() << std::endl;  
}

Number of objects: 1
Number of objects: 3
Number of objects: 1
Ari Hietanen
  • 1,749
  • 13
  • 15