By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
446,421 Members | 1,089 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 446,421 IT Pros & Developers. It's quick & easy.

Containers & Pointers, Discussion

P: n/a
Hi... Today I was trying to find the best way to handle elements in
Containers. I've found 3 appraoches but all do have pros and cons...

1. std::vector<MyClass>
- inefficient
- you have to write assing an copy constructor
- to add new element into container you do need 2 lines of code
+ very comfortable use of algorhitms from STL

2. std::vector<MyClass*>
+ efficient
+ only one line of code when adding new element
- problems with removing elements, you have to delete them first
from memory.

3. std::vector< CountedPtr<MyClass
* CountedPtr is a smart ptr, that tracks references of a pointer
+ efficient
+ only one line of code when adding new element
+ no problems with deleting pointers (will delete itself on loosing
reference count
- i'm not able to find a way to use STL algorhitms like for_each,
mem_fun ...

I feel like the third approach is the best I can use, the problem is
it has one big disadvantage I mentioned. I'd be really glad if someone
knew how to bypass it..

Well, anyway, if someone has any suggestions, advices, just tell me,
I'd really like to know what is the best way to store elements in
Containers.

Jun 5 '07 #1
Share this Question
Share on Google+
7 Replies


P: n/a
ms****@gmail.com wrote:
Hi... Today I was trying to find the best way to handle elements in
Containers. I've found 3 appraoches but all do have pros and cons...

1. std::vector<MyClass>
- inefficient
- you have to write assing an copy constructor
- to add new element into container you do need 2 lines of code
+ very comfortable use of algorhitms from STL

2. std::vector<MyClass*>
+ efficient
+ only one line of code when adding new element
- problems with removing elements, you have to delete them first
from memory.

3. std::vector< CountedPtr<MyClass
* CountedPtr is a smart ptr, that tracks references of a pointer
+ efficient
+ only one line of code when adding new element
+ no problems with deleting pointers (will delete itself on loosing
reference count
- i'm not able to find a way to use STL algorhitms like for_each,
mem_fun ...

I feel like the third approach is the best I can use, the problem is
it has one big disadvantage I mentioned. I'd be really glad if someone
knew how to bypass it..

Well, anyway, if someone has any suggestions, advices, just tell me,
I'd really like to know what is the best way to store elements in
Containers.
You can use approach 2. Add a deletion policy to MyClass that can
intelligently delete the pointer depending on a condition. For example:

template <template <typename Tclass deletion_policy>
class MyClass{
};

template <typename T>
class deletion_policy{
};
MyClass<deletion_policy<condition m;
Jun 5 '07 #2

P: n/a
ms****@gmail.com wrote:
3. std::vector< CountedPtr<MyClass
* CountedPtr is a smart ptr, that tracks references of a pointer
+ efficient
yes, it depends on what you mean. you can pass the vectors by reference,
and the vector<Objectwon't be copied. Additionally, using a
vector<Object*or any other pointer type, you usually need to
separately allocate each object independently, which can become very
expensive for large numbers of small objects. For example, it's not
possible to store the pixels of an image in a vector<Pixel*>...
+ only one line of code when adding new element
+ no problems with deleting pointers (will delete itself on loosing
reference count
- i'm not able to find a way to use STL algorhitms like for_each,
mem_fun ...
I can't understand why... you can do something like this, for example:

#include <boost/shared_ptr.hpp>
#include <vector>
#include <iostream>
#include <algorithm>

struct print_element
{
template <typename T>
void operator()(const T& o){ std::cout << *o << " "; }
};

int main()
{
std::vector<boost::shared_ptr<int v;
v.push_back(boost::shared_ptr<int>(new int(3)));
v.push_back(boost::shared_ptr<int>(new int(4)));

std::for_each(v.begin(), v.end(), print_element());
}

what problem are you experiencing with function objects?
>
I feel like the third approach is the best I can use, the problem is
it has one big disadvantage I mentioned. I'd be really glad if someone
knew how to bypass it..
as usual,it depends on the context in which you are using the approach.
Surely enough, there are a lot of situation in which the third approach
is very advantageous..
Well, anyway, if someone has any suggestions, advices, just tell me,
I'd really like to know what is the best way to store elements in
Containers.
Forget about a general best way ;)

Regards,

Zeppe

Jun 5 '07 #3

P: n/a
Thanks Zeppe..
what problem are you experiencing with function objects?
std::for_each( players_.begin(), players_.end(),
std::mem_fun( &MyClass::Foo ) );

Am I able to do this? My compiler throws errors..
And to Fei Liu, I'm not very into the templates, so I don't understand
what you mean..

Jun 5 '07 #4

P: n/a
ms****@gmail.com wrote:
Thanks Zeppe..
>what problem are you experiencing with function objects?

std::for_each( players_.begin(), players_.end(),
std::mem_fun( &MyClass::Foo ) );

Am I able to do this? My compiler throws errors..
And to Fei Liu, I'm not very into the templates, so I don't understand
what you mean..
It's going to be difficult then, because when you start using STL, you
are in the templates...AFAIK you shouldn't have any problem with
approach 3 as long as the smart pointer provides 'correct' copy behavior
per your application.

Fei
Jun 5 '07 #5

P: n/a
ms****@gmail.com wrote:
Thanks Zeppe..
>what problem are you experiencing with function objects?

std::for_each( players_.begin(), players_.end(),
std::mem_fun( &MyClass::Foo ) );

Am I able to do this? My compiler throws errors..
I would suggest you to post a small code example the next time, because,
you know, it saves some time to us to see the problem you are
experiencing faster.

Anyway, you're actually right, mem_fun is not able to solve the template
matching for shared_ptr<Foo>... he expects Foo*. If you are using the
boost library, you can use the boost::mem_fn function that overcomes
this problem. If you are using your own reference counted pointer, you
have got to write your own mem_fun (at a glance, it shouldn't be too
difficult). Consider this example:

#include <boost/shared_ptr.hpp>
#include <vector>
#include <iostream>
#include <algorithm>
#include <functional>
#include <string>
#include <boost/mem_fn.hpp>

class Player
{
public:
Player(const std::string& name) : name_(name) { }
void printName() {
std::cout << "name: " << name_ << std::endl;
}
private:
std::string name_;
};

int main()
{
std::vector<boost::shared_ptr<Player players;
players.push_back(boost::shared_ptr<Player>(
new Player("Th4EbilKill4")));
players.push_back(boost::shared_ptr<Player>(
new Player("Muffin Man")));

std::for_each( players.begin(), players.end(),
boost::mem_fn( &Player::printName ) );

}

>
And to Fei Liu, I'm not very into the templates, so I don't understand
what you mean..
well, i'm (a little bit) more in the template maybe, and that code seems
broken :) It declares a template template argument, that is a way to
pass a template as a template argument without being constrained to
instantiate it as a concrete type before. But in the example this is done.

Anyway, it's not possible to embed a deletion policy inside of the
object itself that is going to be allocated, because i doesn't know
about how it has been allocated. The solution 3 is the best one, if you
want a vector of pointer objects (whose greater advantage is to allow
polymorphic containers, more than performances, in my opinion) and you
want to get rid of the deallocation (which is a good idea, provided that
the container is actually the owner of the object, in a design sense).

Regards,

Zeppe
Jun 5 '07 #6

P: n/a
Zeppe wrote:
>
>>
And to Fei Liu, I'm not very into the templates, so I don't understand
what you mean..

well, i'm (a little bit) more in the template maybe, and that code seems
broken :) It declares a template template argument, that is a way to
pass a template as a template argument without being constrained to
instantiate it as a concrete type before. But in the example this is done.

Anyway, it's not possible to embed a deletion policy inside of the
object itself that is going to be allocated, because i doesn't know
about how it has been allocated. The solution 3 is the best one, if you
It's possible but I think there is misunderstanding on my part about the
original problem. It's a question of whether not how about the deletion.
It's enough that MyClass have a property to indicate if a MyClass
object should be deleted before removed from container.
Jun 5 '07 #7

P: n/a
Fei Liu wrote:
Zeppe wrote:
>>
>>>
And to Fei Liu, I'm not very into the templates, so I don't understand
what you mean..

well, i'm (a little bit) more in the template maybe, and that code
seems broken :) It declares a template template argument, that is a
way to pass a template as a template argument without being
constrained to instantiate it as a concrete type before. But in the
example this is done.

Anyway, it's not possible to embed a deletion policy inside of the
object itself that is going to be allocated, because i doesn't know
about how it has been allocated. The solution 3 is the best one, if you

It's possible but I think there is misunderstanding on my part about the
original problem. It's a question of whether not how about the deletion.
It's enough that MyClass have a property to indicate if a MyClass
object should be deleted before removed from container.
I really can't understand how a MyClass object can understand when a
pointer to it is being removed from a container. Can you give me a
little example code to explain the concept?

regards,

Zeppe
Jun 5 '07 #8

This discussion thread is closed

Replies have been disabled for this discussion.