vector<*C> and vector<C>

This is a discussion on vector<*C> and vector<C> within the C++ Programming forums, part of the General Programming Boards category; Originally Posted by Todd Burch OK, I understand. (I'm not a C++ expert, if you haven't figured that out yet). ...

  1. #16
    and the hat of sweating
    Join Date
    Aug 2007
    Location
    Toronto, ON
    Posts
    3,545
    Quote Originally Posted by Todd Burch View Post
    OK, I understand. (I'm not a C++ expert, if you haven't figured that out yet).

    Why won't this work:

    vector<int *> vi;
    int i;
    vi.push_back(&i);

    ?
    It might work, but as soon as i goes out of scope, you have a dangling pointer.

  2. #17
    Absent Minded Programmer
    Join Date
    May 2005
    Posts
    964
    This is how you never repeat data with boost:

    Code:
    #ifndef RESOURCE_MANAGER_H
    #define RESOURCE_MANAGER_H
    #include <vector>
    #include <map>
    #include <string>
    #include <boost\shared_ptr.hpp>
    #include <boost\weak_ptr.hpp>
    
    template< typename T_ >
    class Resource_Manager
    {  
    
    public:
    
    	typedef T_ value_type; // std library convention 
    
    	typedef boost::shared_ptr<T_> Resource_Ptr;
    	typedef boost::weak_ptr<T_> Resource_Observer;
    	typedef std::map< std::string, Resource_Ptr > Resource_Map;
    
    	Resource_Manager<T_>() {};
    	~Resource_Manager<T_>() {};
    
    	Resource_Observer Request_Resource(const std::string & name)
    	{
    		Resource_Map::iterator  it = mResources.find(name);
    
    		if (it == mResources.end())
    		{
    			Resource_Ptr Raw_Resource(new T_);
    			Raw_Resource->Load(name);
    			mResources.insert(std::make_pair(name, Raw_Resource));
    			Resource_Observer Resource(Raw_Resource);
    			return Resource;
    		}
    		else
    		{
    			return Resource_Observer(it->second);
    		}
    	}
    
    	void Request_Resource_Removal(const std::string & name)
    	{
    		Resource_Map::iterator it = mResources.find(name);
    
    		if (it != mResources.end())
    		{
    			mResources.erase(it);
    		}
    	}
    
    private:
    	Resource_Map  mResources;
    };
    
    #endif
    Basically, the idea is to create a shared pointer for each individual resource item, use an ID to find the single shared pointer to the data, and instead of duplicating data we create a boost::weak_ptr and return it and boost pretty much handles all the cleanup for you.
    Last edited by Shamino; 01-04-2008 at 12:06 PM.
    Sometimes I forget what I am doing when I enter a room, actually, quite often.

  3. #18
    Captain Crash brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,239
    Quote Originally Posted by Angelina View Post
    I'm not very familiar with the boost library and not keen on mixing that in now.

    I was wondering if there is any more "standard" solution?
    Boost. People who won't use it are masochists.

  4. #19
    Absent Minded Programmer
    Join Date
    May 2005
    Posts
    964
    Quote Originally Posted by brewbuck View Post
    Boost. People who won't use it are masochists.
    Quite correct, I tried doing this without boost and soon found myself with a headache trying to figure out dynamic memory allocation and deallocation on my own.

    So I took 10 minutes to get the boost libraries and now I use it with most of my programs.
    Sometimes I forget what I am doing when I enter a room, actually, quite often.

  5. #20
    Registered User
    Join Date
    Jan 2005
    Posts
    7,317
    Many libraries in boost are in almost standard. AFAIK the ptr containers library is not in the next standard, but it is still widely used and tested because it is a part of boost.

    Switching to a ptr_vector is probably a better solution than creating your own version of it.

    Another option is to change the class C to make copying less expensive. for example, if you only need to copy the class when it is inside the vector, then you can move its implementation into a single struct that is held via shared_ptr (another boost item that will be in the next standard). That way you don't have to change the syntax of when you use the vector, you only have to change the implementation of the particular class that is currently slow to copy.

    Remember, though, that the solution above assumes the class won't break any other code if you switch to a shared implementation copy versus a cloned implementation copy.

  6. #21
    C++まいる!Cをこわせ! Elysia's Avatar
    Join Date
    Oct 2007
    Posts
    22,554
    Alternatively, if you don't like *(my_vector_of_pointers_to_obgects[i]), you can also do my_vector_of_pointers_to_obgects->at(i).
    Looks better too.
    Last edited by Elysia; 01-04-2008 at 01:48 PM.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  7. #22
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,893
    Has different behaviour, though - an additional index check, and a throw if the check fails.
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

  8. #23
    C++まいる!Cをこわせ! Elysia's Avatar
    Join Date
    Oct 2007
    Posts
    22,554
    Which is a good thing.
    If the index doesn't exist and you use [], you get undefined behavior (bad) or crash.
    If the index doesn't exist when you use at, you get an exception. You can handle it and your program can correct the error and continue execution. Or you could just not handle the exception and then the program will crash or display a fancy error message and terminate.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  9. #24
    and the hat of sweating
    Join Date
    Aug 2007
    Location
    Toronto, ON
    Posts
    3,545
    Quote Originally Posted by Elysia View Post
    Which is a good thing.
    If the index doesn't exist and you use [], you get undefined behavior (bad) or crash.
    If the index doesn't exist when you use at, you get an exception. You can handle it and your program can correct the error and continue execution. Or you could just not handle the exception and then the program will crash or display a fancy error message and terminate.
    Unless you're already doing your own bounds checking in your own code to make it impossible to pass an invalid index. In that case, using .at() is just a waste of CPU time.

  10. #25
    C++まいる!Cをこわせ! Elysia's Avatar
    Join Date
    Oct 2007
    Posts
    22,554
    In 99.99&#37; of the time, it doesn't matter unless you are writing very time-sensitive code.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  11. #26
    Registered User
    Join Date
    Sep 2006
    Posts
    835
    GCC has the -D_GLIBCXX_DEBUG flag, which in particular causes [] to do bounds checking - see

    http://gcc.gnu.org/onlinedocs/libstdc++/debug.html

    so one can do a debug build with bounds checking, then recompile without the flag without changing the source later, which I prefer to using at(), the bounds checking of which can't be turned off. I don't know if other compilers have a similar feature.

  12. #27
    and the hat of sweating
    Join Date
    Aug 2007
    Location
    Toronto, ON
    Posts
    3,545
    Exactly as this book suggests: Use a checked STL implementation

Page 2 of 2 FirstFirst 12
Popular pages Recent additions subscribe to a feed

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