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