Like Tree2Likes

Static vector of shared_ptr

This is a discussion on Static vector of shared_ptr within the C++ Programming forums, part of the General Programming Boards category; I have a vector declared static as follows: Code: template <class T> class Grid{ static std::vector<std::vector<std::shared_ptr<T>>> *cell_grid; The errors I ...

  1. #1
    Registered User
    Join Date
    May 2010
    Posts
    178

    Static vector of shared_ptr

    I have a vector declared static as follows:

    Code:
    template <class T> class Grid{
    	static std::vector<std::vector<std::shared_ptr<T>>> *cell_grid;
    The errors I am getting are unresolved external symbols related to main where I declare objects of my template class.

    Any idea why I am unable to make this vector static?

  2. #2
    Registered User
    Join Date
    Oct 2006
    Posts
    2,153
    the line of code you have there declares the existence of the vector, but does not allocate storage for it. you need to add a line outside your class definition as the actual definition of Grid::cell_grid.

  3. #3
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    20,981
    Why do you declare a pointer to a vector?
    iMalc likes this.
    C + C++ Compiler: MinGW port of GCC
    Version Control System: Bazaar

    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  4. #4
    Registered User
    Join Date
    May 2010
    Posts
    178
    Quote Originally Posted by laserlight View Post
    Why do you declare a pointer to a vector?
    The vector may get large and I don't want to pass a copy but rather a pointer. If this is not good coding style, I am happy to change it.

  5. #5
    Registered User
    Join Date
    May 2010
    Posts
    178
    Quote Originally Posted by Elkvis View Post
    the line of code you have there declares the existence of the vector, but does not allocate storage for it. you need to add a line outside your class definition as the actual definition of Grid::cell_grid.
    That part of the code you can't see but in the constructor of the templated class, I do create dynamic memory for the vector.

  6. #6
    the hat of redundancy hat nvoigt's Avatar
    Join Date
    Aug 2001
    Location
    Hannover, Germany
    Posts
    3,138
    That doesn't make sense. If it's static, it exists once per class (once per T here because Grid<int> is another class than Grid<double>) and you shouldn't allocate memory once per instance of a class.

    Are you sure that ALL grids of type int should share the same cell_grid?
    hth
    -nv

    She was so Blonde, she spent 20 minutes looking at the orange juice can because it said "Concentrate."

    When in doubt, read the FAQ.
    Then ask a smart question.

  7. #7
    Registered User
    Join Date
    May 2010
    Posts
    178
    What I am trying to do, but failing to do as I continue to learn c++, is to have a template base class place objects of its' derived classes into a singleton vector of smart pointers to the base class objects. I chose to make that vector static to facilitate this but somehow was discouraged by the compiler that rendered all manner of errors related to inheritance and external symbol errors.

    Here is an example of what I am referring to:

    Code:
    template <class T> class Foo{
        static std::vector<std::vector<std::shared_ptr<T>>> *a2D_vector;
    public:
        Foo() {
            a2D_vector = new std::vector<std::vector<std::shared_ptr<T>>> (20, std::vector<std::shared_ptr<T>(20, nullptr));
        }
        virtual ~Foo() {}
    };
    
    class Boo : Foo{
    public:
    };
    
    class Poo : Foo{
    public:
    };
    When objects of Boo and Poo are made, they will Grid<Boo> and Grid<Foo> but share the a2D_vector such that shared pointers to the derived classes will reside in a2D_vector.

    This is the essence of what I desire to do but lack of experience and unfamiliarity has me at a loss and the compiler is winning!!! HELP!!!
    Last edited by Imanuel; 01-24-2013 at 06:23 AM.

  8. #8
    Registered User
    Join Date
    May 2010
    Posts
    178
    Quote Originally Posted by nvoigt View Post
    That doesn't make sense. If it's static, it exists once per class (once per T here because Grid<int> is another class than Grid<double>) and you shouldn't allocate memory once per instance of a class.

    Are you sure that ALL grids of type int should share the same cell_grid?
    All Grid<Derived> should share the same cell_grid, yes. I am doing this to avoid additional tracking overhead and make it so that smart pointers to the derived objects all exist in the same container making them easy to track and call .release() on with no leaks.

    The only way I know of that all objects of a class can share the same member is to make that member static and the derived classes pass smart pointers of themselves to the base class for inclusion into the shared 2D vector.

    If this is incorrect, bad form, never should be done, etc. then I am open to learn.
    Last edited by Imanuel; 01-24-2013 at 06:22 AM.

  9. #9
    Registered User
    Join Date
    May 2010
    Posts
    178
    Quote Originally Posted by Elkvis View Post
    the line of code you have there declares the existence of the vector, but does not allocate storage for it. you need to add a line outside your class definition as the actual definition of Grid::cell_grid.
    I have tried many different things in an attempt to define cell_grid by adding a line outside my class definition but I do not know how to define this. Still generating many errors and I am simply too inexperienced to figure this out.

  10. #10
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    20,981
    Quote Originally Posted by Imanuel
    The vector may get large and I don't want to pass a copy but rather a pointer. If this is not good coding style, I am happy to change it.
    For that, you should use pass by (const) reference instead.

    Quote Originally Posted by Imanuel
    When objects of Boo and Poo are made, they will Grid<Boo> and Grid<Foo> but share the a2D_vector such that shared pointers to the derived classes will reside in a2D_vector.
    This is a little confusing... What is Grid and Foo then? It looked like you renamed Grid to Foo in your newer example.

    Basically, it sounds like you want to have a base class template that will have a static member vector of smart pointers such that for each derived class, one object will be stored in that vector. Is this correct? Oh, and why do you want to do this? Maybe there is a better way.
    C + C++ Compiler: MinGW port of GCC
    Version Control System: Bazaar

    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  11. #11
    Registered User
    Join Date
    May 2010
    Posts
    178
    Quote Originally Posted by laserlight View Post
    For that, you should use pass by (const) reference instead.


    This is a little confusing... What is Grid and Foo then? It looked like you renamed Grid to Foo in your newer example.

    Basically, it sounds like you want to have a base class template that will have a static member vector of smart pointers such that for each derived class, one object will be stored in that vector. Is this correct? Oh, and why do you want to do this? Maybe there is a better way.
    I agree, I confused this a bit. Foo<Boo> and Foo<Poo> smart pointers to these derived objects will reside in a shared vector. I will remove the pointer to vector as it appears unnecessary. What you described above,
    Quote Originally Posted by laserlight View Post
    sounds like you want to have a base class template that will have a static member vector of smart pointers such that for each derived class, one object will be stored in that vector. Is this correct?
    This is correct laserlight but I admit it may not be the best idea.

    The reason I want to do this is to track objects in a vector and deal with those objects directly rather than, perhaps, placing pseudo representations of those objects and keeping track of their position within the grid. That would also involve more work but I am open to more work if it gets the job done.

  12. #12
    Registered User
    Join Date
    Apr 2006
    Posts
    2,012
    Quote Originally Posted by Imanuel View Post
    What I am trying to do, but failing to do as I continue to learn c++, is to have a template base class place objects of its' derived classes into a singleton vector of smart pointers to the base class objects. I chose to make that vector static to facilitate this but somehow was discouraged by the compiler that rendered all manner of errors related to inheritance and external symbol errors.

    Here is an example of what I am referring to:

    Code:
    template <class T> class Foo{
        static std::vector<std::vector<std::shared_ptr<T>>> *a2D_vector;
    public:
        Foo() {
            a2D_vector = new std::vector<std::vector<std::shared_ptr<T>>> (20, std::vector<std::shared_ptr<T>(20, nullptr));
        }
        virtual ~Foo() {}
    };
    
    class Boo : Foo{
    public:
    };
    
    class Poo : Foo{
    public:
    };
    When objects of Boo and Poo are made, they will Grid<Boo> and Grid<Foo> but share the a2D_vector such that shared pointers to the derived classes will reside in a2D_vector.

    This is the essence of what I desire to do but lack of experience and unfamiliarity has me at a loss and the compiler is winning!!! HELP!!!
    We can probably figure out why the compiler is whining, but it sounds like you have a very bad design.

    Why does Grid need to be a template? You could just make it have a vector of shared_pointer's to Foo here.
    It is too clear and so it is hard to see.
    A dunce once searched for fire with a lighted lantern.
    Had he known what fire was,
    He could have cooked his rice much sooner.

  13. #13
    Registered User
    Join Date
    May 2010
    Posts
    178
    Quote Originally Posted by King Mir View Post
    We can probably figure out why the compiler is whining, but it sounds like you have a very bad design.

    Why does Grid need to be a template? You could just make it have a vector of shared_pointer's to Foo here.
    I chose a template for Grid to pass in objects of the derived classes. If this is poor design, I am open to change it to whatever is best practice.

  14. #14
    Registered User
    Join Date
    Apr 2006
    Posts
    2,012
    Just use pointers to Foo. A pointer to a derived class can be implicitly converted to a pointer to a base class.
    It is too clear and so it is hard to see.
    A dunce once searched for fire with a lighted lantern.
    Had he known what fire was,
    He could have cooked his rice much sooner.

  15. #15
    the hat of redundancy hat nvoigt's Avatar
    Join Date
    Aug 2001
    Location
    Hannover, Germany
    Posts
    3,138
    Can you give a real world example for this? With real classnames so we can maybe suggest a better solution? Right now I don't even know what you are trying to do
    hth
    -nv

    She was so Blonde, she spent 20 minutes looking at the orange juice can because it said "Concentrate."

    When in doubt, read the FAQ.
    Then ask a smart question.

Page 1 of 3 123 LastLast
Popular pages Recent additions subscribe to a feed

Similar Threads

  1. std::tr1::shared_ptr question
    By StainedBlue in forum C++ Programming
    Replies: 13
    Last Post: 07-18-2010, 11:48 AM
  2. Replies: 8
    Last Post: 12-30-2008, 01:20 PM
  3. When to use shared_ptr?
    By hpesoj in forum C++ Programming
    Replies: 15
    Last Post: 07-22-2008, 04:33 AM
  4. static vector<...> in class problem.
    By alkis_y3k in forum C++ Programming
    Replies: 5
    Last Post: 01-29-2003, 03:13 PM
  5. vector static abstract data structure in C?
    By Unregistered in forum C Programming
    Replies: 2
    Last Post: 11-05-2001, 04:02 PM

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21