473,387 Members | 1,353 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,387 software developers and data experts.

operator= function

Hi Everyone,

I was just overloading operator = for a class and i have a problem in
one case...

class A
{
A& operator=(const A& obj)
{
return *this;
// please ignore the logic of this function
}
};

int main()
{
A a,b
a = b; //works fine
if(a=b) // causes compile time error as the operator=() returns a
reference to A and not a BOOL.
{
printf("both the objects are the same\n");
}
else
{
printf("both the objects are different\n");
}
}
return(0);
}

Now, i tried to overload operator=() function, but overloading just
based on the return type doesn't make sense.
So is there anyway to solve this problem, so that the user of the
class can get to work in both the cases just like any built in type?

Thanks in advance!!!
Dec 4 '07 #1
24 1874
Rahul wrote:
Hi Everyone,

I was just overloading operator = for a class and i have a problem in
one case...

class A
{
A& operator=(const A& obj)
{
return *this;
// please ignore the logic of this function
}
};

int main()
{
A a,b
a = b; //works fine
if(a=b) // causes compile time error as the operator=() returns a
reference to A and not a BOOL.
{
printf("both the objects are the same\n");
}
else
{
printf("both the objects are different\n");
}
}
return(0);
}

Now, i tried to overload operator=() function, but overloading just
based on the return type doesn't make sense.
So is there anyway to solve this problem, so that the user of the
class can get to work in both the cases just like any built in type?
A simple way would be to *also* provide a conversion function to type
'bool' in your 'A' class:

class A {
...
operator bool() const { return true; }
};

Or any other conversion function that yields a type that can be used
in a logical expression.

Now, let me ask you, why do you think you need assignment in the 'if'
expression

if (a = b)

instead of comparison

if (a == b)

? Or did you not know that those are two different operators?

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
Dec 4 '07 #2
On Dec 4, 8:46 pm, "Victor Bazarov" <v.Abaza...@comAcast.netwrote:
Rahul wrote:
Hi Everyone,
I was just overloading operator = for a class and i have a problem in
one case...
class A
{
A& operator=(const A& obj)
{
return *this;
// please ignore the logic of this function
}
};
int main()
{
A a,b
a = b; //works fine
if(a=b) // causes compile time error as the operator=() returns a
reference to A and not a BOOL.
{
printf("both the objects are the same\n");
}
else
{
printf("both the objects are different\n");
}
}
return(0);
}
Now, i tried to overload operator=() function, but overloading just
based on the return type doesn't make sense.
So is there anyway to solve this problem, so that the user of the
class can get to work in both the cases just like any built in type?

A simple way would be to *also* provide a conversion function to type
'bool' in your 'A' class:

class A {
...
operator bool() const { return true; }
};

Or any other conversion function that yields a type that can be used
in a logical expression.

Now, let me ask you, why do you think you need assignment in the 'if'
expression

if (a = b)

instead of comparison

if (a == b)

? Or did you not know that those are two different operators?
Yes i do. My point is to extend the support provided by c++ for
built-in types to custom types.
int a,b;
a=b; //works fine
if(a=b) // too works fine depending on the value of a.
V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
Dec 4 '07 #3
On Tue, 04 Dec 2007 07:41:52 -0800, Rahul wrote:
Hi Everyone,

I was just overloading operator = for a class and i have a problem in
one case...

class A
{
A& operator=(const A& obj)
{
return *this;
// please ignore the logic of this function
}
};

int main()
{
A a,b
a = b; //works fine
if(a=b) // causes compile time error as the operator=() returns a
reference to A and not a BOOL.
{
printf("both the objects are the same\n");
}
else
{
printf("both the objects are different\n");
}
}
return(0);
}

Now, i tried to overload operator=() function, but overloading just
based on the return type doesn't make sense. So is there anyway to solve
this problem, so that the user of the class can get to work in both the
cases just like any built in type?
First of all - for integer types statement
if (a=b)
tests if b is zero, not if a and b are the same (after executing this
they are for sure the same).
Second - possibility of assignment in 'if' expression is rather a
misfeature and I don't see any point in extending this possibility.

--
Tadeusz B. Kopec (tk****@NOSPAMPLEASElife.pl)
How many "coming men" has one known! Where on earth do they all go to?
-- Sir Arthur Wing Pinero
Dec 4 '07 #4
On Dec 4, 4:06 pm, Rahul <sam_...@yahoo.co.inwrote:
On Dec 4, 8:46 pm, "Victor Bazarov" <v.Abaza...@comAcast.netwrote:
Rahul wrote:
Hi Everyone,
I was just overloading operator = for a class and i have a problem in
one case...
class A
{
A& operator=(const A& obj)
{
return *this;
// please ignore the logic of this function
}
};
int main()
{
A a,b
a = b; //works fine
if(a=b) // causes compile time error as the operator=() returns a
reference to A and not a BOOL.
{
printf("both the objects are the same\n");
}
else
{
printf("both the objects are different\n");
}
}
return(0);
}
Now, i tried to overload operator=() function, but overloading just
based on the return type doesn't make sense.
So is there anyway to solve this problem, so that the user of the
class can get to work in both the cases just like any built in type?
A simple way would be to *also* provide a conversion function to type
'bool' in your 'A' class:
class A {
...
operator bool() const { return true; }
};
Or any other conversion function that yields a type that can be used
in a logical expression.
Now, let me ask you, why do you think you need assignment in the 'if'
expression
if (a = b)
instead of comparison
if (a == b)
? Or did you not know that those are two different operators?

Yes i do. My point is to extend the support provided by c++ for
built-in types to custom types.
int a,b;
a=b; //works fine
if(a=b) // too works fine depending on the value of a.
V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
if() expects boolean value (or int at least), a=b (assignment) returns
new value of a (equals to b) - the chances of this being boolean or
int are not too good considering the number of different data types
AND objects.

So, what was your question?

If you are overloading the = (assignment) operator, what do you expect
it to return? And how do you expect this return value to be converted
to boolean? And why in hell do you want to overload = operator, unless
you want to clone the object?
So, maybe you ARE trying to overload == (compare) operator after all?
Dec 4 '07 #5
On Tue, 4 Dec 2007 08:06:48 -0800 (PST) in comp.lang.c++, Rahul
<sa*****@yahoo.co.inwrote,
Yes i do. My point is to extend the support provided by c++ for
built-in types to custom types.
int a,b;
a=b; //works fine
if(a=b) // too works fine depending on the value of a.
You should never write an assignment in an if statement. Write it
as
a=b;
if (a) ...

Now, what do you think if(a) should mean, when a is some complex
class you have defined?
>
Dec 4 '07 #6
On 2007-12-04 11:06:48 -0500, Rahul <sa*****@yahoo.co.insaid:
On Dec 4, 8:46 pm, "Victor Bazarov" <v.Abaza...@comAcast.netwrote:
>Rahul wrote:
>>Hi Everyone,
>>I was just overloading operator = for a class and i have a problem in
one case...
>>class A
{
A& operator=(const A& obj)
{
return *this;
// please ignore the logic of this function
}
};
>>int main()
{
A a,b
a = b; //works fine
if(a=b) // causes compile time error as the operator=() returns a
reference to A and not a BOOL.
{
printf("both the objects are the same\n");
}
else
{
printf("both the objects are different\n");
}
}
return(0);
}
>>Now, i tried to overload operator=() function, but overloading just
based on the return type doesn't make sense.
So is there anyway to solve this problem, so that the user of the
class can get to work in both the cases just like any built in type?

A simple way would be to *also* provide a conversion function to type
'bool' in your 'A' class:

class A {
...
operator bool() const { return true; }
};

Or any other conversion function that yields a type that can be used
in a logical expression.

Now, let me ask you, why do you think you need assignment in the 'if'
expression

if (a = b)

instead of comparison

if (a == b)

? Or did you not know that those are two different operators?

Yes i do. My point is to extend the support provided by c++ for
built-in types to custom types.
int a,b;
a=b; //works fine
if(a=b) // too works fine depending on the value of a.
May not be a good idea. The syntax

if (a)
{
// do something
}

is not clear what you're testing for here. Code readability should be
highly sought for. Even with native data-types like integers, it's
better to write

if (n != 0) ...

than just

if (n) ...

unless you worry about performance, at which I would think a smart
compiler would generate equivalent codes for both cases anyway.

Also, don't overload the operator bool() just to support the if-test.
You might get yourself into trouble in other situations with this
implicit conversion.

My suggestion is to be explicit and have an method like
bool isValid() const;
so that your if statement reads more explicitly

if ((a=b).isValid()) ...

--

-kira

Dec 4 '07 #7
On Dec 4, 5:06 pm, Rahul <sam_...@yahoo.co.inwrote:
Yes i do. My point is to extend the support provided by c++ for
built-in types to custom types.
int a,b;
a=b; //works fine
if(a=b) // too works fine depending on the value of a.
For what definition of "works"? For historical reasons, it's
formally legal (although there have been proposals to deprecate
it). It's only intentional use in real code is obfuscation,
however, and good compilers will generally warn if you do it.
the correct way of writing this is in two statements:

a = b ;
if ( a != 0 ) { /* ... */ }

Add the necessary == and != operators to your class, and this
will work.

--
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
Dec 5 '07 #8
On Dec 4, 8:44 pm, Kira Yamato <kira...@earthlink.netwrote:
On 2007-12-04 11:06:48 -0500, Rahul <sam_...@yahoo.co.insaid:
[...]
is not clear what you're testing for here. Code readability
should be highly sought for. Even with native data-types like
integers, it's better to write
if (n != 0) ...
than just
if (n) ...
Support for the "if (n)" notation is really just a historical
abherition. Originally, C didn't have a boolean type; you had
to simulate it with int. And of course, "if ( n )" *is* the
correct way to write a test of a boolean variable.

When bool was added to C++, the original proposal was also to
deprecate the implicit conversions of int to bool. In the end,
this was dropped, because it was felt that it would break way
too much code.
unless you worry about performance, at which I would think a
smart compiler would generate equivalent codes for both cases
anyway.
Even a dumb compiler. Even before bool, the compiler needs some
sort of boolean value to make a binary test. Internally, you
generally cannot simply make a conditional jump on an integral
value. (This wasn't necessarily true for older processors.)
The result is that if an expression is used in a boolean
context, and the top node is not a comparison (which sets the
processor's condition codes), the compiler inserts a node with
the comparison. Whether you write "if ( n )" or "if ( n != 0
)", the expression trees used to generate the code are normally
identical.
Also, don't overload the operator bool() just to support the
if-test. You might get yourself into trouble in other
situations with this implicit conversion.
My suggestion is to be explicit and have an method like
bool isValid() const;
so that your if statement reads more explicitly
if ((a=b).isValid()) ...
Don't do that either. With very few exceptions, a single
statement should to one, and only one thing, if you want your
code to be readable. An if statement is flow control, and so
shouldn't modify state.

--
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
Dec 5 '07 #9
Victor Bazarov wrote:
>Also, don't overload the operator bool() just to support the if-test.
You might get yourself into trouble in other situations with this
implicit conversion.

Yes, that's why some folks define 'operator void*()' instead.
So that things like:

int i = std::cout + 3;

don't work, since it would be so dangerous if it did...
>My suggestion is to be explicit and have an method like
bool isValid() const;
so that your if statement reads more explicitly

if ((a=b).isValid()) ...

Ouch. I still think that even

if (a=b, a.isValid())

is better. But nothing beats

a = b;
if (a.isValid())
As long as you want a to exist outside the if scope.

if (MyType a = somefunc())
{
}

I sometimes use that when I need to use dynamic_cast to handle things
differently based on the dynamic type (Using some external libraries that
give me no other choice):

BaseClass* base = somefunc();
// ...
if (Derived1* d1 = dynamic_cast<Derived1*>(base))
{
// do something
}
else if (Derived2* d2 = dynamic_cast<Derived2*>(base))
{
// do something else
}

vs:

BaseClass* base = somefunc();
// ...
Derived1* d1 = dynamic_cast<Derived1*>(base);
if (d1 != 0)
{
// do something
}
else
{
Derived1* d2 = dynamic_cast<Derived2*>(base);
if (d2 != 0)
{
// do something else
}
}

If you have a loop, you might even need to duplicate things:

while (MyType a = somefunc())
{
// do something with a
}

vs:

MyType a = somefunc();
while (a)
{
a = somefunc();
// do something with a
}

I consider the first variant more readable.

Dec 5 '07 #10
On Dec 4, 11:53 pm, "Victor Bazarov" <v.Abaza...@comAcast.netwrote:
Kira Yamato wrote:
On 2007-12-04 14:56:17 -0500, "Victor Bazarov"
<v.Abaza...@comAcast.netsaid:
Kira Yamato wrote:
[..] The syntax
>if (a)
{
// do something
}
>is not clear what you're testing for here.
Of course not! Who in their right mind would name a variable 'a'?
But imagine that the variable is 'statusIsValid' (and its type is not
necessarily 'bool'). What prevents me from writing
if (statusIsValid)
{
// do something
}
?
I was speaking from the OP's context. He's not likely to be using a
boolean flag. Instead, he's using some object of some class which he
also wants to test as a boolean also. He is trying to copy the
situation with the native type like the 'int'.
His code, which you ripped completely out so that the context is
gone, was
class A
{
A& operator=(const A& obj)
{
return *this;
// please ignore the logic of this function
}
};
int main()
{
A a,b
a = b; //works fine
if(a=b) // causes compile time error as the operator=() returns a
reference to A and not a BOOL.
{
printf("both the objects are the same\n");
}
else
{
printf("both the objects are different\n");
}
}
return(0);
}
This is a bad idea on at least a couple of level.
First, the statement
if (a=b)
looks suspiciously a typo to
if (a==b).
Second,
if (someobject)
is never explicit in what you are trying to test for about the object.
In the case of 'int', it is tolerated because it is stipulated in the
standard what that means. But for a user-defined class, the meaning
is not obvious from that if statement alone.
This is what I was talking about.

Now, you ripped my code completely out and jerked us back to the OP's
example which doesn't really present _any_ context simply because there
is no design intent recognisable in it. It's OK, I'll try to gently
nudge us back to the discussion on merits of the original syntax.

Imagine (and that will require you to think outside the box, I *am*
holding my breath for this one) that the OP wants to check the success
of the assignment operation. The OP could then define

class A {
bool operator=(const A& other);
};

so that the assignment could be either checked
you will lose the ability to chain:

{
int a, b, c;
a=b=c;//ok
}{
A a, b, c;
a=b=c;//error
}

I prefere a conversion operator to an intrinsic type ,or at least a
checker function like 'auto_ptr::get' or 'some_STL_container::empty'.

regards,
FM.
Dec 5 '07 #11
On Dec 5, 7:06 pm, Rolf Magnus <ramag...@t-online.dewrote:
Victor Bazarov wrote:
Also, don't overload the operator bool() just to support the if-test.
You might get yourself into trouble in other situations with this
implicit conversion.
Yes, that's why some folks define 'operator void*()' instead.

So that things like:

int i = std::cout + 3;

don't work, since it would be so dangerous if it did...
My suggestion is to be explicit and have an method like
bool isValid() const;
so that your if statement reads more explicitly
if ((a=b).isValid()) ...
Ouch. I still think that even
if (a=b, a.isValid())
is better. But nothing beats
a = b;
if (a.isValid())

As long as you want a to exist outside the if scope.

if (MyType a = somefunc())
{

}

I sometimes use that when I need to use dynamic_cast to handle things
differently based on the dynamic type (Using some external libraries that
give me no other choice):

BaseClass* base = somefunc();
// ...
if (Derived1* d1 = dynamic_cast<Derived1*>(base))
{
// do something}

else if (Derived2* d2 = dynamic_cast<Derived2*>(base))
{
// do something else

}

vs:

BaseClass* base = somefunc();
// ...
Derived1* d1 = dynamic_cast<Derived1*>(base);
if (d1 != 0)
{
// do something}

else
{
Derived1* d2 = dynamic_cast<Derived2*>(base);
if (d2 != 0)
{
// do something else
}

}

If you have a loop, you might even need to duplicate things:

while (MyType a = somefunc())
{
// do something with a

}

vs:

MyType a = somefunc();
while (a)
{
a = somefunc();
// do something with a

}

I consider the first variant more readable.
enclosing the loop/conditional statement in an extra pair of braces
gives similar functionality(I do not discuss readabilty for now):

{//extra braces
class X* xptr=whatever;
while (xptr){
....
};
};

regards,
FM.
Dec 5 '07 #12
terminator wrote:
On Dec 4, 11:53 pm, "Victor Bazarov" <v.Abaza...@comAcast.netwrote:
>[..]
Imagine (and that will require you to think outside the box, I *am*
holding my breath for this one) that the OP wants to check the
success of the assignment operation. The OP could then define

class A {
bool operator=(const A& other);
};

so that the assignment could be either checked

you will lose the ability to chain:

{
int a, b, c;
a=b=c;//ok
}{
A a, b, c;
a=b=c;//error
}

Chaining is not necessarily a good idea. Neither is the assignment
operator that can fail, of course. In that case it would probably
be best to have a member function that would return 'bool'.
I prefere a conversion operator to an intrinsic type ,or at least a
checker function like 'auto_ptr::get' or 'some_STL_container::empty'.
Well, as we discussed elsethread, conversion to an integral type may
not be the right choice, but conversion to 'void*' could work (like
it does for streams).

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
Dec 5 '07 #13
On Dec 5, 5:06 pm, Rolf Magnus <ramag...@t-online.dewrote:
Victor Bazarov wrote:
[...]
if ((a=b).isValid()) ...
Ouch. I still think that even
if (a=b, a.isValid())
is better. But nothing beats
a = b;
if (a.isValid())
As long as you want a to exist outside the if scope.
I'd say that if it matters, your function is too big.
if (MyType a = somefunc())
{
}
I sometimes use that when I need to use dynamic_cast to handle
things differently based on the dynamic type (Using some
external libraries that give me no other choice):
BaseClass* base = somefunc();
// ...
if (Derived1* d1 = dynamic_cast<Derived1*>(base))
{
// do something}

else if (Derived2* d2 = dynamic_cast<Derived2*>(base))
{
// do something else
You mean, something like:

d1->xxx ;

You might as well move the declaration out of the if, so that
it's readable.

(If I had to chain the tests, of course, I'd probably put each
case in a separate function, with its test.)
}
vs:
BaseClass* base = somefunc();
// ...
Derived1* d1 = dynamic_cast<Derived1*>(base);
if (d1 != 0)
{
// do something}

else
{
Derived1* d2 = dynamic_cast<Derived2*>(base);
if (d2 != 0)
{
// do something else

}
If you have a loop, you might even need to duplicate things:
while (MyType a = somefunc())
{
// do something with a
}
vs:
MyType a = somefunc();
while (a)
{
a = somefunc();
// do something with a
}
I consider the first variant more readable.
No way. It hides an important change of state (and declaration)
in the middle of a condition.

--
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
Dec 6 '07 #14
On Dec 5, 10:31 pm, terminator <farid.mehr...@gmail.comwrote:
On Dec 5, 7:06 pm, Rolf Magnus <ramag...@t-online.dewrote:
[...]
enclosing the loop/conditional statement in an extra pair of braces
gives similar functionality(I do not discuss readabilty for now):
{//extra braces
class X* xptr=whatever;
while (xptr){
....
};
};
And writing clean code, without outlandishly long functions,
eliminates the need for the functionality completely.

--
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
Dec 6 '07 #15
On Dec 6, 12:52 am, "Victor Bazarov" <v.Abaza...@comAcast.netwrote:
terminator wrote:
On Dec 4, 11:53 pm, "Victor Bazarov" <v.Abaza...@comAcast.netwrote:
[..]
Imagine (and that will require you to think outside the box, I *am*
holding my breath for this one) that the OP wants to check the
success of the assignment operation. The OP could then define
class A {
bool operator=(const A& other);
};
so that the assignment could be either checked
you will lose the ability to chain:
{
int a, b, c;
a=b=c;//ok
}{
A a, b, c;
a=b=c;//error
}

Chaining is not necessarily a good idea. Neither is the assignment
operator that can fail, of course. In that case it would probably
be best to have a member function that would return 'bool'.
as long as OP needs a type that follows the syntax for intrisic
types ,chaining must not be dropped.But generally you are right of
course.
I prefere a conversion operator to an intrinsic type ,or at least a
checker function like 'auto_ptr::get' or 'some_STL_container::empty'.

Well, as we discussed elsethread, conversion to an integral type may
not be the right choice, but conversion to 'void*' could work (like
it does for streams).
why do you insist on 'void*'?

regards,
FM.
Dec 6 '07 #16
terminator wrote:
On Dec 6, 12:52 am, "Victor Bazarov" <v.Abaza...@comAcast.netwrote:
>terminator wrote:
>>On Dec 4, 11:53 pm, "Victor Bazarov" <v.Abaza...@comAcast.net>
wrote:
[..]
Imagine (and that will require you to think outside the box, I *am*
holding my breath for this one) that the OP wants to check the
success of the assignment operation. The OP could then define
>>> class A {
bool operator=(const A& other);
};
>>>so that the assignment could be either checked
>>you will lose the ability to chain:
>>{
int a, b, c;
a=b=c;//ok
}{
A a, b, c;
a=b=c;//error
}

Chaining is not necessarily a good idea. Neither is the assignment
operator that can fail, of course. In that case it would probably
be best to have a member function that would return 'bool'.

as long as OP needs a type that follows the syntax for intrisic
types ,chaining must not be dropped.But generally you are right of
course.
>>I prefere a conversion operator to an intrinsic type ,or at least a
checker function like 'auto_ptr::get' or
'some_STL_container::empty'.

Well, as we discussed elsethread, conversion to an integral type may
not be the right choice, but conversion to 'void*' could work (like
it does for streams).

why do you insist on 'void*'?
I don't. It's just another option, which is considered better.
You seem to not like it. Why?

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
Dec 6 '07 #17
On Dec 6, 6:10 pm, "Victor Bazarov" <v.Abaza...@comAcast.netwrote:
terminator wrote:
[...]
why do you insist on 'void*'?
I don't. It's just another option, which is considered better.
Better than what? iostream continues to use it, for historical
reasons, but I think that the generally approved solution today
is either HiddenClass* (where HiddenClass is a private member),
or some sort of pointer to member of HiddenClass; both make it
extremely difficult (and the pointer to member makes it
impossible) for the user to recover an apparently usable pointer
to anything, and thus reduce the chance of mis-use even more.

--
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
Dec 7 '07 #18
On 2007-12-07 07:15:59 -0500, James Kanze <ja*********@gmail.comsaid:
On Dec 6, 6:10 pm, "Victor Bazarov" <v.Abaza...@comAcast.netwrote:
>terminator wrote:

[...]
>>why do you insist on 'void*'?
>I don't. It's just another option, which is considered better.

Better than what? iostream continues to use it, for historical
reasons, but I think that the generally approved solution today
is either HiddenClass* (where HiddenClass is a private member),
or some sort of pointer to member of HiddenClass; both make it
extremely difficult (and the pointer to member makes it
impossible) for the user to recover an apparently usable pointer
to anything, and thus reduce the chance of mis-use even more.
Specifically, the primary justification for returning a
pointer-to-member rather than a pointer to a class type (or to void*,
for that matter) is that you can't delete it. I haven't seen or heard
of any studies indicating that either of these is a significant
problem, however.

--
Pete
Roundhouse Consulting, Ltd. (www.versatilecoding.com) Author of "The
Standard C++ Library Extensions: a Tutorial and Reference
(www.petebecker.com/tr1book)

Dec 7 '07 #19
James Kanze wrote:
On Dec 6, 6:10 pm, "Victor Bazarov" <v.Abaza...@comAcast.netwrote:
>terminator wrote:

[...]
>>why do you insist on 'void*'?
>I don't. It's just another option, which is considered better.

Better than what?
Better than 'bool'. Better than 'int'.
iostream continues to use it, for historical
reasons, but I think that the generally approved solution today
is either HiddenClass* (where HiddenClass is a private member),
or some sort of pointer to member of HiddenClass; both make it
extremely difficult (and the pointer to member makes it
impossible) for the user to recover an apparently usable pointer
to anything, and thus reduce the chance of mis-use even more.
Yes, that's better still.

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
Dec 7 '07 #20
On Dec 7, 3:06 pm, Pete Becker <p...@versatilecoding.comwrote:
On 2007-12-07 07:15:59 -0500, James Kanze <james.ka...@gmail.comsaid:
On Dec 6, 6:10 pm, "Victor Bazarov" <v.Abaza...@comAcast.netwrote:
terminator wrote:
[...]
>why do you insist on 'void*'?
I don't. It's just another option, which is considered better.
Better than what? iostream continues to use it, for historical
reasons, but I think that the generally approved solution today
is either HiddenClass* (where HiddenClass is a private member),
or some sort of pointer to member of HiddenClass; both make it
extremely difficult (and the pointer to member makes it
impossible) for the user to recover an apparently usable pointer
to anything, and thus reduce the chance of mis-use even more.

Specifically, the primary justification for returning a
pointer-to-member rather than a pointer to a class type (or to void*,
for that matter) is that you can't delete it. I haven't seen or heard
of any studies indicating that either of these is a significant
problem, however.
I've seen it happen at least once. The conversion was always to
false,
so delete 0 didn't complain (crashing the application would have saved
a lot of debugging).
It took us a while to track the bug.

The (not) fun thing is that our operator safe-bool was actually
using the proper pointer to member function idiom but we were
using a broken gcc version (3.3.5 IIRC) that had a regression
that allowed that illegal code to compile (it was fixed in gcc 3.3.6).

HTH,

--
gpd

Dec 7 '07 #21
On Dec 7, 5:39 pm, gpderetta <gpdere...@gmail.comwrote:
On Dec 7, 3:06 pm, Pete Becker <p...@versatilecoding.comwrote:


On 2007-12-07 07:15:59 -0500, James Kanze <james.ka...@gmail.comsaid:
On Dec 6, 6:10 pm, "Victor Bazarov" <v.Abaza...@comAcast.netwrote:
>terminator wrote:
[...]
>>why do you insist on 'void*'?
>I don't. It's just another option, which is considered better.
Better than what? iostream continues to use it, for historical
reasons, but I think that the generally approved solution today
is either HiddenClass* (where HiddenClass is a private member),
or some sort of pointer to member of HiddenClass; both make it
extremely difficult (and the pointer to member makes it
impossible) for the user to recover an apparently usable pointer
to anything, and thus reduce the chance of mis-use even more.
Specifically, the primary justification for returning a
pointer-to-member rather than a pointer to a class type (or to void*,
for that matter) is that you can't delete it. I haven't seen or heard
of any studies indicating that either of these is a significant
problem, however.

I've seen it happen at least once. The conversion was always to
false,
so delete 0 didn't complain (crashing the application would have saved
a lot of debugging).
It took us a while to track the bug.

The (not) fun thing is that our operator safe-bool was actually
using the proper pointer to member function idiom but we were
using a broken gcc version (3.3.5 IIRC) that had a regression
that allowed that illegal code to compile (it was fixed in gcc 3.3.6).
casting to pointer to a type that defines delete can fix that too:

class none_delete{
void operator delete(void *)//can become public
{/*empty*/};
}

operator A::none_delete*()
{
....
return reinterpreit_cast<none_delete *>(result);
};

regards,
FM.
Dec 7 '07 #22
On Dec 6, 8:10 pm, "Victor Bazarov" <v.Abaza...@comAcast.netwrote:
terminator wrote:
On Dec 6, 12:52 am, "Victor Bazarov" <v.Abaza...@comAcast.netwrote:
terminator wrote:
On Dec 4, 11:53 pm, "Victor Bazarov" <v.Abaza...@comAcast.net>
wrote:
[..]
Imagine (and that will require you to think outside the box, I *am*
holding my breath for this one) that the OP wants to check the
success of the assignment operation. The OP could then define
>> class A {
bool operator=(const A& other);
};
>>so that the assignment could be either checked
>you will lose the ability to chain:
>{
int a, b, c;
a=b=c;//ok
}{
A a, b, c;
a=b=c;//error
}
Chaining is not necessarily a good idea. Neither is the assignment
operator that can fail, of course. In that case it would probably
be best to have a member function that would return 'bool'.
as long as OP needs a type that follows the syntax for intrisic
types ,chaining must not be dropped.But generally you are right of
course.
>I prefere a conversion operator to an intrinsic type ,or at least a
checker function like 'auto_ptr::get' or
'some_STL_container::empty'.
Well, as we discussed elsethread, conversion to an integral type may
not be the right choice, but conversion to 'void*' could work (like
it does for streams).
why do you insist on 'void*'?

I don't. It's just another option, which is considered better.
You seem to not like it. Why?
I was not just sure if it was the best,Now I know it was not.

regards,
FM.

Dec 7 '07 #23
On Dec 7, 3:06 pm, Pete Becker <p...@versatilecoding.comwrote:
On 2007-12-07 07:15:59 -0500, James Kanze <james.ka...@gmail.comsaid:
On Dec 6, 6:10 pm, "Victor Bazarov" <v.Abaza...@comAcast.netwrote:
terminator wrote:
[...]
>why do you insist on 'void*'?
I don't. It's just another option, which is considered better.
Better than what? iostream continues to use it, for historical
reasons, but I think that the generally approved solution today
is either HiddenClass* (where HiddenClass is a private member),
or some sort of pointer to member of HiddenClass; both make it
extremely difficult (and the pointer to member makes it
impossible) for the user to recover an apparently usable pointer
to anything, and thus reduce the chance of mis-use even more.
Specifically, the primary justification for returning a
pointer-to-member rather than a pointer to a class type (or to
void*, for that matter) is that you can't delete it.
Adding a private operator delete to HiddenClass would solve that
as well:-).

I'm not that much of a purist. I might use HiddenClass*,
because it only takes one extra line, and it will solve the most
obvious abuses (static_cast, or passing it to a legacy C
function which takes a void*). But quite frankly...
I haven't seen or heard of any studies indicating that either
of these is a significant problem, however.
I've never had (nor heard of) any problems with misuse of the
void* in iostream either. I use HiddenClass in my smart
pointers, as an argument for == and !=, so that the user can
only pass NULL, but that's really about it in practice.

But he said "better":-). And it's a sort of a challenge to
think of how you could detect as many user errors as possible,
even if you'd never actually do it in practice, because the work
involved largely outweighs the actual gain.

--
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
Dec 7 '07 #24
On 2007-12-07 11:14:50 -0500, James Kanze <ja*********@gmail.comsaid:
>
But he said "better":-). And it's a sort of a challenge to
think of how you could detect as many user errors as possible,
even if you'd never actually do it in practice, because the work
involved largely outweighs the actual gain.
The problem is that these exercises tend to become enshrined. The
current WD for C++0x has half a dozen places that advise returning a
pointer-to-member as the implementation-specific return type of a
conversion operator that's intended for testing the state of an object.
Fortunately, most of those are going away, and being replaced with
explict conversion operators.

--
Pete
Roundhouse Consulting, Ltd. (www.versatilecoding.com) Author of "The
Standard C++ Library Extensions: a Tutorial and Reference
(www.petebecker.com/tr1book)

Dec 7 '07 #25

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

2
by: victor75040 | last post by:
Before you all start flaming me, I am not a student and this is not for any homework. Just someone learing c++ on their own. I am now up to the chapter in my book that describes operator...
2
by: Nimmi Srivastav | last post by:
There's a rather nondescript book called "Using Borland C++" by Lee and Mark Atkinson (Que Corporation) which presents a rather good discussion of typecast operator overloading. I am presenting...
7
by: Emanuel Ziegler | last post by:
Hello, I want to do some mathematics with functions. In my case the function classes are very complex, but this simple example has the same problems. To allow calculations that begin with a...
10
by: Piotr Wyderski | last post by:
Hello, is it possible to reuse a friend operator which is defined inside a class? I'd like to obtain the following behaviour: class integer { integer operator +(signed long int v) const...
2
by: wongjoekmeu | last post by:
Hello All, I have a question about a C++ listing that I don't understand from a book that I use to learn C++. In the listing a class String is declared and defined. The beginning look like this...
3
by: y-man | last post by:
Hi, I am trying to get an overloaded operator to work inside the class it works on. The situation is something like this: main.cc: #include "object.hh" #include "somefile.hh" object obj,...
11
by: jakester | last post by:
I am using Visual C++ 2007 to build the code below. I keep getting linkage error. Could someone please tell me what I am doing wrong? The code works until I start using namespace for my objects. ...
14
by: Jess | last post by:
Hi, I read about operator overloading and have a question regarding "operator->()". If I have two classes like this: struct A{ void f(); }; struct B{
8
by: Wayne Shu | last post by:
Hi everyone, I am reading B.S. 's TC++PL (special edition). When I read chapter 11 Operator Overloading, I have two questions. 1. In subsection 11.2.2 paragraph 1, B.S. wrote "In particular,...
2
by: Peng Yu | last post by:
Hi, In the following code, the 'copy' member function works. But the '=' operator does not work. Can somebody let me know why a member function is different from an operator. Thanks, Peng ...
0
by: taylorcarr | last post by:
A Canon printer is a smart device known for being advanced, efficient, and reliable. It is designed for home, office, and hybrid workspace use and can also be used for a variety of purposes. However,...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.