how to free the reference which is initialized in constructor

Y

yccheok

Most of the time, I am using pointer as the reference to other classes.

Now, I am trying to use c++ reference to other class.

Please note that in "pad" class, it is holding a reference to "cell".
"pad"
will initialize the mycell, which is the reference (alias) to "cell"
class. I have the following question:

(1) where will the real copy of cell object stored? is it stored in the
heap memory, just like it
is being allocated through new operator.

(2) who is responsible in deleting the copy of cell aliases by mycell
reference? This is because I found that if I put the statement "delete
&mycell" in the pad destructor, memory violation will happen.

However, if I just leave it alone, I found tat the cell would not be
destructed automatically after pad is destructed :(

here is the output from the program:

=========
output:

cell default x called
pad default x called

pad destructor call
=========



Or should I just use back pointer? Any advice/ suggestion is very much
appreciated.

cheok

---------------------

#include <cstdio>
#include "cell.h"

cell::cell()
{
printf("cell default called\n");
}

cell::cell(const cell &t)
{
printf("cell copy called\n");
}

cell& cell::eek:perator=(const cell &t)
{
printf("cell = called\n");
return *this;
}

cell::~cell()
{
printf("cell destructor call\n");
}
---------------------

#include <cstdio>
#include "pad.h"

pad::pad() : mycell(cell())
{
printf("pad default called\n");
}

pad::pad(const pad &p) : mycell(cell(p.GetCell()))
{
printf("pad copy called\n");
}

pad& pad::eek:perator=(const pad &t)
{
mycell = t.GetCell();

printf("pad= called\n");

return *this;
}

pad::~pad()
{
// Nope! We cannt do that! But who will responsible for deleting
// the copy of cell which is being aliased by mycell???
//
delete &mycell;

printf("pad destructor call\n");
}

const cell& pad::GetCell() const
{
return mycell;
}
---------------------

#include "cell.h"

class pad
{
public:
pad();
pad(const pad &p);
pad& operator=(const pad &t);
~pad();

const cell& GetCell() const;

private:
cell &mycell;
};
 
R

Rolf Magnus

Most of the time, I am using pointer as the reference to other classes.

Now, I am trying to use c++ reference to other class.

Please note that in "pad" class, it is holding a reference to "cell".
"pad" will initialize the mycell, which is the reference (alias) to "cell"
class. I have the following question:

(1) where will the real copy of cell object stored?

There is no copy. There is only a reference to an already existing object.
That's what references are about.

int main()
{
int i = 3;
int j = i; //copy of i
int& k = i; //no copy is made. k is just another name for i and becomes
//invalid as soon as i gets out of scope.
}

If you want a copy, just use an instance as member instead of a reference.
(2) who is responsible in deleting the copy of cell aliases by mycell
reference?

Whoever created the object that your reference refers to.
This is because I found that if I put the statement "delete &mycell" in
the pad destructor, memory violation will happen.

If an object was not created with new, it must not be destroyed with delete.
However, if I just leave it alone, I found tat the cell would not be
destructed automatically after pad is destructed :(

It should already be destroyed before the first use. See below.
#include <cstdio>
#include "cell.h"

cell::cell()
{
printf("cell default called\n");
}

cell::cell(const cell &t)
{
printf("cell copy called\n");
}

cell& cell::eek:perator=(const cell &t)
{
printf("cell = called\n");
return *this;
}

cell::~cell()
{
printf("cell destructor call\n");
}
---------------------

#include <cstdio>
#include "pad.h"

pad::pad() : mycell(cell())


The above line is actually not supposed to compile. I guess you're using an
outdated compiler. cell() creates a temporary cell, and you're not a
allowed to bind a non-const reference to a temporary. It wouldn't make much
sense anyway, since your cell is destroyed immediately after you bind the
reference to it, i.e. before you can even use it.
 
M

mlimber

Rolf said:
(e-mail address removed) wrote: [snip]
(2) who is responsible in deleting the copy of cell aliases by mycell
reference?

Whoever created the object that your reference refers to.
[snip]

Not necessarily. The standard idiom is to pass or return a
std::auto_ptr if the receiver is responsible to delete the object. For
instance, here's a class that is responsible for deleting an int passed
to it in the constructor:

#include <memory>
#include <boost/scoped_ptr.hpp>

struct A
{
A( std::auto_ptr<int>& pi ) : pi_( pi ) {}
// ...
private:
boost::scoped_ptr<int> pi_;
};

For members, I use boost::scoped_ptr, which is similar to std::auto_ptr
but cannot be (destructively) copied. Here's a factory function that
turns over ownership to the client:

std::auto_ptr<int> CreateInt()
{
return std::auto_ptr<int>( new int(42) );
}

Cheers! --M
 
R

Rolf Magnus

mlimber said:
Whoever created the object that your reference refers to.
[snip]

Not necessarily. The standard idiom is to pass or return a
std::auto_ptr if the receiver is responsible to delete the object.

Actually, in this case, the auto_ptr releaves the receiver of the
responsibility to delete the object. The creator already took care of it by
returning an auto_ptr.
 
M

mlimber

Rolf said:
mlimber said:
(2) who is responsible in deleting the copy of cell aliases by mycell
reference?

Whoever created the object that your reference refers to.
[snip]

Not necessarily. The standard idiom is to pass or return a
std::auto_ptr if the receiver is responsible to delete the object.

Actually, in this case, the auto_ptr releaves the receiver of the
responsibility to delete the object. The creator already took care of it by
returning an auto_ptr.

Right, but you could also pass/return a non-smart pointer to the
receiver who then is responsible for deleting it (which the receiver
can do manually or via a smart pointer or whatever):

int* CreateInt() { return new int(42); }
std::auto_ptr<int> pi( CreateInt() );

Of course, the idiom in my previous post is IMHO preferable to this
because the intentions are clearer, responsibilities are explicit, and
misuse is more difficult.

Cheers! --M
 
Y

yccheok

Ya, you are right! This code compiled well under microsoft visual
studio c++ .net 2003. However, when I try it on g++ (GCC) 3.3.5, the
compiler prevent me from compile:

pad.cpp: In constructor `pad::pad()':
pad.cpp:5: error: invalid initialization of non-const reference of type
'cell&'
from a temporary of type 'cell'
pad.cpp: In copy constructor `pad::pad(const pad&)':
pad.cpp:11: error: invalid initialization of non-const reference of
type 'cell&
' from a temporary of type 'cell'

So, does it mean that in this case, I should use pointer instead of
reference for mycell variable?

Thank you.
 

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,769
Messages
2,569,576
Members
45,054
Latest member
LucyCarper

Latest Threads

Top