memory ? about objects within a class

M

Mark K

Im just getting back into C++ after a long hiatus. Ive been coding in
Java for the last 3 years and Im finding it hard to get back into the
swing of things since C++ went standard. Anyhow,,,here's my question

given the following class def and implementation, how should I be
cleaning up my variables?

Also, when implementing the "has a" relationship with other classes
and regular datatypes, when should pointers or just references be
used?

As you can see, I lost most of my C++ knowledge to Java's
over-simplified impl.

Thanks for any clarification

Mark

/*in Customer.h*/
#ifndef COMMON_CUSTOMER_H
#define COMMON_CUSTOMER_H

#include <string>

class Customer
{
public:
Customer();
virtual ~Customer();
const string getName() const ;
void setName( const string & ) ;
private:
string name ;
};

#endif

/* in Customer.cxx */
#include <string>
#include "Customer.h"

Customer::Customer()
{
name = "";
}

Customer::~Customer()
{
//delete name ; <- I know this isn't right, but how do I release this
}

//Or should I be returning a pointer to this reference?
const string Customer::getName() const
{
return this->name ;
}

void Customer::setName( const string &newName)
{
name = newName ;
}
 
V

Victor Bazarov

Mark K said:
Im just getting back into C++ after a long hiatus. Ive been coding in
Java for the last 3 years and Im finding it hard to get back into the
swing of things since C++ went standard. Anyhow,,,here's my question

given the following class def and implementation, how should I be
cleaning up my variables?

See below.
Also, when implementing the "has a" relationship with other classes
and regular datatypes, when should pointers or just references be
used?

Pointers should be used if you are not sure whether during run-time
the "had" object may or may not exist (pointers can be NULL). Use
reference if the lifetime of the object is the same as the object
that has it, but the relationship is not really a "has-a", but more
of a "associated-with".
As you can see, I lost most of my C++ knowledge to Java's
over-simplified impl.

Thanks for any clarification

Mark

/*in Customer.h*/
#ifndef COMMON_CUSTOMER_H
#define COMMON_CUSTOMER_H

#include <string>

class Customer
{
public:
Customer();
virtual ~Customer();
const string getName() const ;
void setName( const string & ) ;
private:
string name ;
};

#endif

/* in Customer.cxx */
#include <string>
#include "Customer.h"

Customer::Customer()
{
name = "";

There is no need to do that. The string 'name' will be set to
}

Customer::~Customer()
{
//delete name ; <- I know this isn't right, but how do I release this

You don't need to. Since the 'name' object is contained within
the 'Customer', it will be destroyed when this Customer is.
}

//Or should I be returning a pointer to this reference?
const string Customer::getName() const


Returing a const ref or a non-const object are both fine.
{
return this->name ;
}

void Customer::setName( const string &newName)
{
name = newName ;
}

Victor
 
J

Jonathan Mcdougall

Im just getting back into C++ after a long hiatus. Ive been coding in
Java for the last 3 years
yurk

Also, when implementing the "has a" relationship with other classes
and regular datatypes, when should pointers or just references be
used?

It always depend, there is (unfortunately) no "right" answer.

Most of the time, you will aggregate an object simply by having it in
the class :

class A
{
private:
Customer c_;

};

And 'c_' will get initialized by A's constructor (you will have to
specify it in the initialization list if Customer's constructor needs
arguments).

The thing with this method is that maybe you don't *know* what to pass
to c_'s constructor, or maybe you don't want c_ at all at that moment.
For example, the user could click something and then you would create
the object. If he does not click anything, you never create it : time
and memory are saved.

In that case, you will need a pointer :

class B
{
private:
Customer *c_;
};

which will be new'ed when you wish and deleted when you must (usually
in the destructor).

The third case would be that your class needs access to another object
of which you don't control the lifetime. In that case, since you do
not 'own' the object, use a reference :

class C
{
private:
Customer &c_;

public:
C(Customer &c) : c_(c)
{
}
};

/*in Customer.h*/
#ifndef COMMON_CUSTOMER_H
#define COMMON_CUSTOMER_H

#include <string>

class Customer
{
public:
Customer();
virtual ~Customer();

Not necessary if not a base class.
const string getName() const ;

If this function returns a string by value (that is, a copy), it is
useless to make it const.
void setName( const string & ) ;
private:
string name ;

This should not compile. Either fully qualify the names (such as
std::string) or put a 'using namespace std;' on top (which is not
recommended though).
};

#endif

/* in Customer.cxx */
#include <string>
#include "Customer.h"

Customer::Customer()
{
name = "";
}

Prefer using initialization lists in ctor :

Customer::Customer()
: name("")
{
}
Customer::~Customer()
{
//delete name ; <- I know this isn't right, but how do I release this
}

You don't have to, std::string is a class. When your Customer object
will get out of scope, it will be destroyed automatically.

the only reason for which you would want to delete something is when
YOU created it :

int main()
{
Customer *c1 = new Customer;
Customer c2;

// you created c1, so delete it
delete c1;

// and you didn't create c2, so don't touch it
// as it will go out of scope, its memory will be released

// if c2 owns any object (like a std::string), they will get
// destroyed automatically
}

You have to make a difference between automatic objects and pointers.
Both of them are deleted correctly by the run-time system, so you
don't want to touch them :

int main()
{
Customer c1;
Customer *c2;

delete &c1; // ouch!!
delete &c2; // ouch!!!
}

The thing is, the pointer could *point* to something you allocated
yourself and this memory must be deleted :

int main()
{
Customer *c1 = new Customer;

delete c1; // you are deleting the Customer object you allocated
// and the *pointer* itself will be deleted by the
// system
}
//Or should I be returning a pointer to this reference?
const string Customer::getName() const
{
return this->name ;
}

No, you return that string by value or reference. The time of
pointers is long gone now, use them only if you must. If you don't
know when to use them, it means you don't need them.

Jonathan
 
K

Karl Heinz Buchegger

Jonathan said:
The thing with this method is that maybe you don't *know* what to pass
to c_'s constructor, or maybe you don't want c_ at all at that moment.
For example, the user could click something and then you would create
the object. If he does not click anything, you never create it : time
and memory are saved.

In that case, you will need a pointer :

class B
{
private:
Customer *c_;
};

which will be new'ed when you wish and deleted when you must (usually
in the destructor).

I think it's worth to emphasize: You want to avoid that case whenever you can.
 

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

Forum statistics

Threads
473,766
Messages
2,569,569
Members
45,042
Latest member
icassiem

Latest Threads

Top