Create a list of class as a member attribute

S

silverburgh.meryl

Hi,

I would like to create a Class which has a list of another class as it
attribute.
I wonder, should I do this:
class B {
private:
vector<A> _listOfA;
}

B::B() {
A a1;
A a2;
_listOfA.push_back(a1);
_listOfA.push_back(a2);
}

or this:

class B {
private:
vector<A*> _listOfA;
}

B::B() {
A* a1 = new A();
A* a2 = new A();
_listOfA.push_back(a1);
_listOfA.push_back(a2);
}

I think #1 is the preferred way in C++. But isn't there is a
performance penalty in #1?
(when you push_back(a1), you are copying a1 to the list of A, right? So
should we do #2, which is pass by reference instead of pass by value?
 
V

Victor Bazarov

I would like to create a Class which has a list of another class as it
attribute.
I wonder, should I do this:
class B {
private:
vector<A> _listOfA;

Provided the compiler knows what 'A' is and what 'vector' is. Also,
consider that naming a _vector_ "list" is potentially confusing.
;
B::B() {
A a1;
A a2;
_listOfA.push_back(a1);
_listOfA.push_back(a2);
}

or this:

class B {
private:
vector<A*> _listOfA;
}
;
B::B() {
A* a1 = new A();
A* a2 = new A();
_listOfA.push_back(a1);
_listOfA.push_back(a2);
}

I think #1 is the preferred way in C++. But isn't there is a
performance penalty in #1?

Performance penalty is unrecognisable until the program is complete and
can be run to collect performance data (like under a profiler, for
example).
(when you push_back(a1), you are copying a1 to the list of A, right? So
should we do #2, which is pass by reference instead of pass by value?

Right, you're copying a1. If copying is expensive, storing pointers can
be a better approach. (BTW, in #2 you're copying 'a1' as well, but it is
merely a pointer, so copying of a pointer is usually cheap). Given the
minuscule amount of code you posted, it's impossible to conclude one way
or the other.

Keep in mind that storing pointers obtained from 'new' requires cleaning
them up at the time when they are not needed any longer (in the d-tor, for
example). You've not shown how or where that is done. If it's not done,
you have a "memory leak".

V
 
D

Dakka

Hi,

I would like to create a Class which has a list of another class as it
attribute.
I wonder, should I do this:
class B {
private:
vector<A> _listOfA;
}

B::B() {
A a1;
A a2;
_listOfA.push_back(a1);
_listOfA.push_back(a2);
}

or this:

class B {
private:
vector<A*> _listOfA;
}

B::B() {
A* a1 = new A();
A* a2 = new A();
_listOfA.push_back(a1);
_listOfA.push_back(a2);
}

I think #1 is the preferred way in C++. But isn't there is a
performance penalty in #1?
(when you push_back(a1), you are copying a1 to the list of A, right? So
should we do #2, which is pass by reference instead of pass by value?

#1 creates a copy of the object as you said and #2 creates a copy of the
pointer to the object. So, depending on the complexity of the object
there can be a performance hit. I generally use pointers for non-trivial
objects and copies of the object for trivial ones. There is no "right"
way. Both are valid. Of course with the pointer version you need to
delete the objects explicitly.
--dakka
 
T

TB

(e-mail address removed) sade:
Hi,

I would like to create a Class which has a list of another class as it
attribute.
I wonder, should I do this:
class B {
private:
vector<A> _listOfA;
}

B::B() {
A a1;
A a2;
_listOfA.push_back(a1);
_listOfA.push_back(a2);
}

or this:

class B {
private:
vector<A*> _listOfA;
}

B::B() {
A* a1 = new A();
A* a2 = new A();
_listOfA.push_back(a1);
_listOfA.push_back(a2);
}

I think #1 is the preferred way in C++.

Don't adhere to an assumed "preferred" way. It actually
boils down to the demands of your design. And the code
you've shown lacks vital context to say which of
the two you should use. But as a question in general, see
my first sentence.
 
A

Axter

Hi,

I would like to create a Class which has a list of another class as it
attribute.
I wonder, should I do this:
class B {
private:
vector<A> _listOfA;
}

B::B() {
A a1;
A a2;
_listOfA.push_back(a1);
_listOfA.push_back(a2);
}

or this:

class B {
private:
vector<A*> _listOfA;
}

B::B() {
A* a1 = new A();
A* a2 = new A();
_listOfA.push_back(a1);
_listOfA.push_back(a2);
}

I recommend you avoid using pointers in general, unless you're sure you
need it.
Make sure you do a performance test that shows you'll need this added
complexity.
Sometimes having to call new, actually makes your code less efficient,
because some libraries have poor implementation for new.

If you do have to use pointers, then I recommend you use smart pointers
in your container, instead of raw pointers.
You can use the boost::shared_ptr or the following cow_ptr
http://code.axter.com/cow_ptr.h
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,484
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top