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

private member variables

P: n/a
Hello all.

I have a design question.

assuming we have
class Bar {...} // body omitted for clarity

class Foo
{
// should Bar be implemented as a pointer or not here ?
Bar *m_bar; // OPTION 1
// or
Bar m_bar; // OPTION 2

.... // body omitted for clarity

Foo::Foo()
// OPTION 1
m_bar = new Bar;
m_bar.setID(1);
// or
m_bar.setID(1);

I have seen both of these methods used, so I am wondering if there
is any memory or speed differences between the two ?
Jun 27 '08 #1
Share this Question
Share on Google+
5 Replies


P: n/a
On May 9, 4:50 pm, wiskey5alpha <wiskey5Al...@gmail.comwrote:
I have a design question.
assuming we have
class Bar {...} // body omitted for clarity
class Foo
{
// should Bar be implemented as a pointer or not here ?
Bar *m_bar; // OPTION 1
// or
Bar m_bar; // OPTION 2
It depends somewhat on Bar, and what you're doing with it. In
general, use a value if you can, a pointer if you have to.
... // body omitted for clarity
Foo::Foo()
// OPTION 1
m_bar = new Bar;
m_bar.setID(1);
That would be m_bar->setID( 1 ) ;
// or
m_bar.setID(1);
I have seen both of these methods used, so I am wondering if
there is any memory or speed differences between the two ?
Probably not enough to worry about. On the other hand, using a
member object is a lot surer and more reliable.

--
James Kanze (GABI Software) email:ja*********@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

Jun 27 '08 #2

P: n/a
"wiskey5alpha" <wi**********@gmail.comwrote in message
news:d6**********************************@j22g2000 hsf.googlegroups.com...
Hello all.

I have a design question.

assuming we have
class Bar {...} // body omitted for clarity

class Foo
{
// should Bar be implemented as a pointer or not here ?
Bar *m_bar; // OPTION 1
// or
Bar m_bar; // OPTION 2

... // body omitted for clarity

Foo::Foo()
// OPTION 1
m_bar = new Bar;
m_bar.setID(1);
// or
m_bar.setID(1);

I have seen both of these methods used, so I am wondering if there
is any memory or speed differences between the two ?
I don't think you will see any significant change in memory or speed.

But the reasons why you use an instance of the object or a pointer to the
object would be many.

When you use an instance, the object is instantiated when the class Foo is
instantiated and destroyed when Foo is. But you have to declare the class
Bar for class Foo to us it. On a small class design that might not be a
problem. On large projects the dependency between headers could be
overwhelming.

When you us a pointer to the object you need to instantiate and destroy the
object yourself. But you don't have to declare the full class. E.g.

In Bar.h

class bar

{

Jun 27 '08 #3

P: n/a
wiskey5alpha wrote:
Hello all.

I have a design question.

assuming we have
class Bar {...} // body omitted for clarity

class Foo
{
// should Bar be implemented as a pointer or not here ?
Bar *m_bar; // OPTION 1
// or
Bar m_bar; // OPTION 2

... // body omitted for clarity

Foo::Foo()
// OPTION 1
m_bar = new Bar;
m_bar.setID(1);
// or
m_bar.setID(1);

I have seen both of these methods used, so I am wondering if there
is any memory or speed differences between the two ?
As others are stating,
Bar m_bar;
is preferred. When you can't, for whatever reason, then you would use a
pointer
Bar* m_bar;
or wrap Bar in a class hiding the pointer. Using pointers when you don't
have to brings up maintance issues that you have to remember to deal with,
new if you need to, if you do new make sure you delete, point it to the
correct place if you're not newing it, etc... Pointers are a level of
indirection and you should only add a layer of indirection when you have to,
or there is a good sound design issue it resolves.

--
Jim Langston
ta*******@rocketmail.com
Jun 27 '08 #4

P: n/a
On May 9, 10:50*am, wiskey5alpha <wiskey5Al...@gmail.comwrote:
Hello all.

[..]
Thank you all. I really appreciate the help !
Jun 27 '08 #5

P: n/a
On May 9, 10:50 am, wiskey5alpha <wiskey5Al...@gmail.comwrote:
Hello all.

I have a design question.

assuming we have
class Bar {...} // body omitted for clarity

class Foo
{
// should Bar be implemented as a pointer or not here ?
Bar *m_bar; // OPTION 1
// or
Bar m_bar; // OPTION 2

... // body omitted for clarity

Foo::Foo()
// OPTION 1
m_bar = new Bar;
m_bar.setID(1);
// or
m_bar.setID(1);

I have seen both of these methods used, so I am wondering if there
is any memory or speed differences between the two ?
To add to the other comments, you should use initializer lists rather
than the constructor body (http://www.parashift.com/c++-faq-lite/
ctors.html#faq-10.6), and prefer to use the constructor parameters to
initialize member variables and set class invariants rather than
manual setting things up as you do with Bar::setID(), which could
allow internally invalid objects to hang around and cause trouble.
(Consider also the named parameter idiom,
http://www.parashift.com/c++-faq-lit...tml#faq-10.18).

Also, to prevent memory leaks, you should generally use smart pointers
(cf. http://www.parashift.com/c++-faq-lit...html#faq-16.22
and the following FAQs) and RAII containers like std::vector (http://
http://www.parashift.com/c++-faq-lit....html#faq-34.1) rather than
raw pointers. In the first place, with smart pointers you needn't
destroy the created objects explicitly in your destructor, and in the
second place, you gain exception safety in your constructors (cf.
http://www.parashift.com/c++-faq-lit....html#faq-17.2) and
elsewhere. Consider:

class Foo
{
Bar *m_bar1;
Bar *m_bar2;
public:
Foo()
: m_bar1( new Bar( 1 ) )
, m_bar2( new Bar( 2 ) )
{}

~Foo()
{
delete m_bar2;
delete m_bar1;
}
// ...
};

If the construction of Foo::m_bar2 throws an exception (out of memory,
invalid parameter, whatever), then the memory from m_bar1 is leaked
since the destructor is not called unless the constructor completed
successfully. Probably better is to change the member variable types
from Bar* to std::tr1::shared_ptr<Bar(aka, boost::shared_ptr<Barif
your standard C++ library doesn't have TR1 yet) or similar. Then you
can drop the destructor altogether and you have exception safety in
your constructor (cf. the Law of the Big Two, http://www.artima.com/cppsource/bigtwoP.html),
but the rest of your code remains unchanged and happily oblivious that
it is now smarter.

One of your goals should be to write code that is easy to use
correctly and hard to use incorrectly, and another should be to let
the compiler do the work of releasing resources like memory, files,
and locks for you rather than doing it explicitly (Sutter and
Alexandrescu, _C++ Coding Standards_, Item 13 and
http://www.research.att.com/~bs/bs_faq2.html#finally).

Cheers! --M
Jun 27 '08 #6

This discussion thread is closed

Replies have been disabled for this discussion.