pointer & reference doubt!

T

toton

HI,
One more small doubt from today's mail.
I have certain function which returns a pointer (sometimes a const
pointer from a const member function).
And certain member function needs reference (or better a const
reference).

for eg,
const PointRange* points = cc.points(ptAligned);

cc.points is a const member function which returns a const pointer to
class PointRange.
This member function (from a different class) needs a const reference
to PointRange.
convolveNearEdge(const PointRange& points,const Kernel& kernel, ...) {}


I am passing it the reference as,
convolveNearEdge(*points,getKernel1(),velocity);

I do not need a null in the function thus a reference. also I make
assure points passed to convolveNearEdge is not null.

My question is, in the process do anywhere copy of the class occures
silently? I have no problem if it copies a pointer. But do not want a
copy of the class even temporarily.

Thus fundamentally , if I have a pointer, say int* x; *x = 10; then
int& y = *x is essentially a reference to the value pointed by x? and
without any overload?


Thanks
 
V

Victor Bazarov

toton said:
I have certain function which returns a pointer (sometimes a const
pointer from a const member function).
And certain member function needs reference (or better a const
reference).

for eg,
const PointRange* points = cc.points(ptAligned);

cc.points is a const member function which returns a const pointer to
class PointRange.
This member function (from a different class) needs a const reference
to PointRange.
convolveNearEdge(const PointRange& points,const Kernel& kernel, ...)
{}


I am passing it the reference as,
convolveNearEdge(*points,getKernel1(),velocity);

I do not need a null in the function thus a reference. also I make
assure points passed to convolveNearEdge is not null.

My question is, in the process do anywhere copy of the class occures
silently?

Unless there is a conversion from PointRange to something inside the
'convolveNearEdge' function... No, returning a pointer does not need
to make a copy, passing a reference doesn't either.
I have no problem if it copies a pointer. But do not want a
copy of the class even temporarily.

You can always put a breakpoint in the copy constructor and see if it
gets hit, you know...
Thus fundamentally , if I have a pointer, say int* x; *x = 10; then

Ahem... That's a bad idea. 'x' points to nothing and you try to
dereference it...
int& y = *x is essentially a reference to the value pointed by x? and
without any overload?

Yes, supposedly. Using 'y' after that is just like using '*x'.

V
 
T

toton

Victor said:
Unless there is a conversion from PointRange to something inside the
'convolveNearEdge' function... No, returning a pointer does not need
to make a copy, passing a reference doesn't either.


You can always put a breakpoint in the copy constructor and see if it
gets hit, you know...


Ahem... That's a bad idea. 'x' points to nothing and you try to
dereference it...
Very bad .... . May be this is the only reason I never use a pointer
which is not a class member. read the code as . int* x = new int; *x =
10; int& y = *x;
and at last delete x;
Yes, supposedly. Using 'y' after that is just like using '*x'.

V
Thus i feel that a pointer & reference can be freely interchangable
without any overhead provided the pointer is pointing to a valid
object.
I usually pass a const / non const reference as it always hold a valid
object & easier syntax. However I prefer return as pointer over
reference (const / non const) , when I am not supposed to return value,
because sometimes I forget to work with the reference, and use a copy
instead, which do not serve the purpose of returning reference.
like instead of writing
test11& t1 = t2.t();
occationally end up with
test11 t1 = t2.t();
:(
Any suggestion regurding this problem?

Thanks
 
T

toton

Victor said:
Unless there is a conversion from PointRange to something inside the
'convolveNearEdge' function... No, returning a pointer does not need
to make a copy, passing a reference doesn't either.


You can always put a breakpoint in the copy constructor and see if it
gets hit, you know...


Ahem... That's a bad idea. 'x' points to nothing and you try to
dereference it...
Very bad .... . May be this is the only reason I never use a pointer
which is not a class member. read the code as . int* x = new int; *x =
10; int& y = *x;
and at last delete x;
Yes, supposedly. Using 'y' after that is just like using '*x'.

V
Thus i feel that a pointer & reference can be freely interchangable
without any overhead provided the pointer is pointing to a valid
object.
I usually pass a const / non const reference as it always hold a valid
object & easier syntax. However I prefer return as pointer over
reference (const / non const) , when I am not supposed to return value,
because sometimes I forget to work with the reference, and use a copy
instead, which do not serve the purpose of returning reference.
like instead of writing
test11& t1 = t2.t();
occationally end up with
test11 t1 = t2.t();
:(
Any suggestion regurding this problem?

Thanks
 
V

Victor Bazarov

toton said:
Victor said:
toton said:
[...]
Thus fundamentally , if I have a pointer, say int* x; *x = 10; then

Ahem... That's a bad idea. 'x' points to nothing and you try to
dereference it...
Very bad .... . May be this is the only reason I never use a pointer
which is not a class member. read the code as . int* x = new int; *x =
10; int& y = *x;
and at last delete x;

:)

Usually

int* x = new int(10);

is preferred over

int* x = new int;
*x = 10;

It would be a good habit to get into...
Thus i feel that a pointer & reference can be freely interchangable
without any overhead provided the pointer is pointing to a valid
object.

Well, yes, that's true. Remember, though, that if you want to use any
overloaded operators, you have to write (*ptr). Kinda ugly. But you
are right, in that case there is only the syntactical difference.
I usually pass a const / non const reference as it always hold a valid
object & easier syntax. However I prefer return as pointer over
reference (const / non const) , when I am not supposed to return
value, because sometimes I forget to work with the reference, and use
a copy instead, which do not serve the purpose of returning reference.

Returning a copy does serve its purpose, though. It's not the same as
returning a reference, and not only WRT copying.
like instead of writing
test11& t1 = t2.t();
occationally end up with
test11 t1 = t2.t();
:(
Any suggestion regurding this problem?

"Regurding"?

Anyway, just be careful. If you want to weed out all places where you
initialise an object (instead of a reference), disable the copy c-tor
and the compiler will barf. [of course it will barf on legal copying
as well, and you'll have to deal with that]. After removing all those
unwanted object copy-initialisations, re-enable the copy c-tor (if you
need it, that is).

V
 
T

toton

Victor said:
toton said:
Victor said:
toton wrote:
[...]
Thus fundamentally , if I have a pointer, say int* x; *x = 10; then

Ahem... That's a bad idea. 'x' points to nothing and you try to
dereference it...
Very bad .... . May be this is the only reason I never use a pointer
which is not a class member. read the code as . int* x = new int; *x =
10; int& y = *x;
and at last delete x;

:)

Usually

int* x = new int(10);

is preferred over

int* x = new int;
*x = 10;

It would be a good habit to get into...
Thus i feel that a pointer & reference can be freely interchangable
without any overhead provided the pointer is pointing to a valid
object.

Well, yes, that's true. Remember, though, that if you want to use any
overloaded operators, you have to write (*ptr). Kinda ugly. But you
are right, in that case there is only the syntactical difference.
I usually pass a const / non const reference as it always hold a valid
object & easier syntax. However I prefer return as pointer over
reference (const / non const) , when I am not supposed to return
value, because sometimes I forget to work with the reference, and use
a copy instead, which do not serve the purpose of returning reference.

Returning a copy does serve its purpose, though. It's not the same as
returning a reference, and not only WRT copying.
Yes, returning reference is different than returning copy. I am
comparing returning reference and returning pointer. Not them with
returning copy.
"Regurding"?
Thus, when I need to return the class member object instead to
1) someone modify it (may be rare case)
2) const reference / pointer , just for user to use it.
Now if I need to return a object as reference just for modification (
or const object just for usage, and the object is big, and ''assume"
return value optimization is not there, so return by value is an
overhead)
Then,
If I have class like
lass test11{
public:
test11(int x){ }
private:
//test11(const test11& t);
};
class test22{
private:
test11* _t;
public:
test11& t(){
return *_t;
}
};

Now,
test22 t2;
test11& t1 = t2.t();
This statement serves purpose, as I want user to "use test11 to use and
modify" not a copy of it. (may be, because I want it, or because it is
big enough not to be copied)
However by mistake if the user writes,
test22 t2;
test11 t1 = t2.t();
He unknowingly gets a copy and modifies it.
The same may be true if I return a const reference.
One method to prevent such mistake is to make the copy ctor private, or
not defined. However that may not be the solution as,
1) test11 may need copy ctor (say, test22 stores a vector<test11>
instead a single one)
2) I am not interested to prevent copy permanently, I just want to warn
about the mistake done "unknowingly"
Two solution so far I can think,
1) return a pointer / const pointer instead of reference/ const
reference.
Yes, as you suggested, if test11 has overloaded operator then direct
use of the class may be writing one more line to convert the pointer to
reference and then use it.
2) marke the copy ctor explicit.
Thus the code
test11 t1 = t2.t(); wont work. One need to write either
test11& t1 = t2.t(); => which is what I wanted usually.
or test11 t1(t2.t()); => which shows user clearly wants a copy.
I am seeking some advice "regarding" this kind of problem.
Anyway, just be careful. If you want to weed out all places where you
initialise an object (instead of a reference), disable the copy c-tor
and the compiler will barf. [of course it will barf on legal copying
as well, and you'll have to deal with that]. After removing all those
unwanted object copy-initialisations, re-enable the copy c-tor (if you
need it, that is).
I do it whenever possible. I can not do it when I need one - to -many
or many-to-one composition (association, aggregation) , as I usually
use stl containers for that purpose. However for any one-to-one
association / aggregation that is possible.

Many many thanks for the reply.
 
V

Victor Bazarov

toton wrote:
[..]
Thus, when I need to return the class member object instead to
1) someone modify it (may be rare case)
2) const reference / pointer , just for user to use it.
Now if I need to return a object as reference just for modification (
or const object just for usage, and the object is big, and ''assume"
return value optimization is not there, so return by value is an
overhead)
Then,
If I have class like
lass test11{
public:
test11(int x){ }
private:
//test11(const test11& t);
};
class test22{
private:
test11* _t;
public:
test11& t(){
return *_t;
}
};

Now,
test22 t2;
test11& t1 = t2.t();
This statement serves purpose, as I want user to "use test11 to use
and modify" not a copy of it. (may be, because I want it, or because
it is big enough not to be copied)
However by mistake if the user writes,
test22 t2;
test11 t1 = t2.t();
He unknowingly gets a copy and modifies it.

Why "unknowingly"? Why don't you trust your user to do the right thing?
The same may be true if I return a const reference.

Yes. So?
One method to prevent such mistake is to make the copy ctor private,
or not defined. However that may not be the solution as,
1) test11 may need copy ctor (say, test22 stores a vector<test11>
instead a single one)
2) I am not interested to prevent copy permanently, I just want to
warn about the mistake done "unknowingly"
Two solution so far I can think,
1) return a pointer / const pointer instead of reference/ const
reference.

Thinking back, you're trying to prevent the user from doing what maybe
the user wholeheartedly intends. There is no reason. You help the user
to avoid copying by returning a reference. What the user does with it
is not your business any more.

Same with pointers.
Yes, as you suggested, if test11 has overloaded operator then direct
use of the class may be writing one more line to convert the pointer
to reference and then use it.
2) marke the copy ctor explicit.
Thus the code
test11 t1 = t2.t(); wont work. One need to write either
test11& t1 = t2.t(); => which is what I wanted usually.
or test11 t1(t2.t()); => which shows user clearly wants a copy.
I am seeking some advice "regarding" this kind of problem.

I think you're seeing a problem where there isn't any.

V
 
T

toton

Victor said:
toton wrote:
[..]
Thus, when I need to return the class member object instead to
1) someone modify it (may be rare case)
2) const reference / pointer , just for user to use it.
Now if I need to return a object as reference just for modification (
or const object just for usage, and the object is big, and ''assume"
return value optimization is not there, so return by value is an
overhead)
Then,
If I have class like
lass test11{
public:
test11(int x){ }
private:
//test11(const test11& t);
};
class test22{
private:
test11* _t;
public:
test11& t(){
return *_t;
}
};

Now,
test22 t2;
test11& t1 = t2.t();
This statement serves purpose, as I want user to "use test11 to use
and modify" not a copy of it. (may be, because I want it, or because
it is big enough not to be copied)
However by mistake if the user writes,
test22 t2;
test11 t1 = t2.t();
He unknowingly gets a copy and modifies it.

Why "unknowingly"? Why don't you trust your user to do the right thing?
The same may be true if I return a const reference.

Yes. So?
One method to prevent such mistake is to make the copy ctor private,
or not defined. However that may not be the solution as,
1) test11 may need copy ctor (say, test22 stores a vector<test11>
instead a single one)
2) I am not interested to prevent copy permanently, I just want to
warn about the mistake done "unknowingly"
Two solution so far I can think,
1) return a pointer / const pointer instead of reference/ const
reference.

Thinking back, you're trying to prevent the user from doing what maybe
the user wholeheartedly intends. There is no reason. You help the user
to avoid copying by returning a reference. What the user does with it
is not your business any more.

Same with pointers.
Yes, as you suggested, if test11 has overloaded operator then direct
use of the class may be writing one more line to convert the pointer
to reference and then use it.
2) marke the copy ctor explicit.
Thus the code
test11 t1 = t2.t(); wont work. One need to write either
test11& t1 = t2.t(); => which is what I wanted usually.
or test11 t1(t2.t()); => which shows user clearly wants a copy.
I am seeking some advice "regarding" this kind of problem.

I think you're seeing a problem where there isn't any.
May be. May not be also.
The reason is that, not every one is an expert C++ programmer. Even a
large number is not at all a C++ programmer. While parameter passing by
reference enhances the program(it takes reference, even when exact
reference is not passed)
like
object o; //o is the object itself
foo(o); //takes the object itself. where void foo(object o);
foo_ref(o); //takes the reference. where void foo(const object& o);
So, unknowingly (i.e not going through the reference manual of the API)
user promotes the idea of rererence!
Where for return by reference, user unknowingly may ignore the idea of
reference.
Pointer is surely not the same case, as it has a syntax difference in
the function declaration and function calling, otherwise the compiler
will object. (May be this mistake forced C# to use ref keyward in both
function declaration and calling).
Expert programmer do not have a problem. But average programmer may
fall into silent trap with just an '&' difference.
One of the problem relating copy ctor as I said, is on the line of
constructor with a single argument. And copy constructor is also a
single argument constructor. So the same warning may get applied to
copy constructor also.
check http://www.horstmann.com/cpp/pitfalls.html explicit array
section.
Also one can notice how many times people ask for a solution for copy
ctor & assignment operator. And for large class most people give copy
ctor a deep copy while assignment as shallow one or otherways (like
blitz array) .

Anyway, the whole thing is a matter of taste. I thought about that, as
I checked many programmer do this mistake, and while asked for the
reason the answer was, "I do it all the time!" , "I hadn't checked the
API documentation", "Oh! sorry for the mistake", or even "I don't know
all the details, it is your duty to correct it!".
Surely it is not valid for you as an user (as you are one of the main
trouble shooter in this newsgroup , others are surely Kai-Uwe Bux,
Frederick Gotham, Bart, Rolf Magnus, mlimber). I know that C++ relies
on programer to write a correct program (on contrary Java forces it.
Just for comparison check Java & C++ container model, and iterator
model) , but sometimes the later one is benificial.
Again, it is the question , to whom you are addressing! . "One size
does not fit all." True for program as well as programmer!
Thanks
 
V

Victor Bazarov

toton said:
[..] not every one is an expert C++ programmer. Even a
large number is not at all a C++ programmer. While parameter passing
by reference enhances the program(it takes reference, even when exact
reference is not passed)
like
object o; //o is the object itself
foo(o); //takes the object itself. where void foo(object o);
foo_ref(o); //takes the reference. where void foo(const object& o);
So, unknowingly (i.e not going through the reference manual of the
API) user promotes the idea of rererence!
Where for return by reference, user unknowingly may ignore the idea of
reference.

Yes, that's so. Just like if you ride a bus, you trust the driver to
do the right thing, but you don't have the freedom to stop any time you
want or to go anywhere you want. When you drive yourself, you do have
the freedom, but you have to learn driving, you have to pass the exam,
you have to take more risks than a passenger in a bus...

Freedom doesn't come cheap. "Unknowingly" in this case to me is the
same as "purposely ignoring". Shouldn't be your problem.
[..]
Anyway, the whole thing is a matter of taste.

I do not agree. It's not. You give them a sophisticated tool (in the
form of a library with functions returning *references*). They do not
want or do not care to use it to its fullest extend. Who's to blame?
I thought about that, as
I checked many programmer do this mistake, and while asked for the
reason the answer was, [..]

Here is the truth: if you strive to protect the users of your "C++"
library from making those mistakes, you will *inevitably* recreate Java
with all its troubles and problems and niceties and goodness. There is
no free cheese, except in a mouse trap.

V
 

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,997
Messages
2,570,241
Members
46,831
Latest member
RusselWill

Latest Threads

Top