Re: A question regarding cast operator
Quote:
Originally Posted by
superbonzo
yes I did; mine was a rhetoric question because I didn't actually find any; moreover, I know you like bullet lists :D ...
XD
About casts: OK. But I think it's fair to let the OP decide. There's the smal matter of "experience required in order to do so", in which case: do what the C++ experts say :D.
But there's always room for re-evaluation of adopted practices. Fair enough?
Re: A question regarding cast operator
Quote:
Originally Posted by
superbonzo
just for the sake of discussion, which are them ?
He's correct that, by a novice, they might be faulty used but as they are searchable (IMO) that's not a big issue. A faulty C++ cast should easily be detected and corrected during a peer-review. I don't know about you but the first thing I do in a review is a search for _cast without the need to invent any clever regular expression. For me finding a C-style cast is a cause for a review rejection of the code.
Re: A question regarding cast operator
Quote:
Originally Posted by Danny Kalev
Derived *p= pbase;
int result= 12.56; //yes, this code compiles
void*opaque =&myobj;
On what compiler would the first line here compile? :eek:
Not one I would like to use, that's for sure.
And while the second line will compile, a compiler is free to give a warning instead - g++ does. A static_cast will prevent this warning though.
Re: A question regarding cast operator
There might be a little difference in case multiple-inheritance is involved (eg class C : B, A) . When "upcasting", the address of the "Base pointer" might be offset from that of the derived pointer.
static_cast takes it into account.
C-cast, on the other hand, I am unsure. Maybe it does, maybe it doesn't.
I'm not saying the C-cast is wrong, but the fact that I've never really been sure about how C-Cast works in C++ is why I don't use C-cast in C++ ...
Re: A question regarding cast operator
Quote:
Originally Posted by
nuzzle
I've never found a reason to use the conversion operator so I may be wrong here but if you define a conversion operator why do you need to cast at all? Why don't you simply do,
B* pB = a; // #3
All of #1, #2 and #3 work but if you remove the conversion operator from A none of them will. That means they're all functionally equivalent in this case. They all simply invoke the conversion operator.
Generally they're not equivalent though. When you cast explicitly you're recommended to use one of the "new" more targeted casts. In this case it would be static_cast.
I agree with you. If someone uses B* pB = (B*)a, then it is not good to use C style casting in C++. If someone uses B* pB = static_cast<B*>(a), then there is a dilemma that why would cast operator is equivalent to static_cast instead of dynamic_cast or reinterpret_cast?
Re: A question regarding cast operator
Quote:
Originally Posted by LarryChen
If someone uses B* pB = static_cast<B*>(a), then there is a dilemma that why would cast operator is equivalent to static_cast instead of dynamic_cast or reinterpret_cast?
Not dynamic_cast because you are not casting from a base class pointer to a derived class pointer (or you are, but you are absolutely sure, on pain of death, that the base class pointer points to an object of that derived class). Since you have defined the conversion, it then makes sense for it to be static_cast rather than reinterpret_cast since the conversion is supposedly "safe" (i.e., when reading the code, your mental alarm bells are supposed to ring louder when you see a reinterpret_cast than a static_cast, at least in theory).
Re: A question regarding cast operator
Quote:
Originally Posted by
laserlight
Not dynamic_cast because you are not casting from a base class pointer to a derived class pointer (or you are, but you are absolutely sure, on pain of death, that the base class pointer points to an object of that derived class). Since you have defined the conversion, it then makes sense for it to be static_cast rather than reinterpret_cast since the conversion is supposedly "safe" (i.e., when reading the code, your mental alarm bells are supposed to ring louder when you see a reinterpret_cast than a static_cast, at least in theory).
Why are you so sure I am not casting from a base class pointer to a derived class pointer? I can design my cast operator like a dynamic casting operator. Also I don't really follow why you would think my cast operator can NOT be a reinterpret_cast? Any more explainations? Thanks.
Re: A question regarding cast operator
Quote:
Originally Posted by LarryChen
Why are you so sure I am not casting from a base class pointer to a derived class pointer?
In your example, A and B are not related through inheritance. Furthermore, I did give leeway, as per the part in parentheses.
Quote:
Originally Posted by LarryChen
I can design my cast operator like a dynamic casting operator.
That would be completely pointless since you might as well just use dynamic_cast. (Also, see my answer concerning reinterpret_cast.)
Also, you need to be precise in your terminology. Your operator B* member is an example of a conversion function, also known as a conversion operator, but when I read "cast operator", I think of static_cast, dynamic_cast, or Boost's lexical_cast, in which case I would expect a function template from you that generically performs some kind of type coercion rather than a specific case of a conversion function.
Quote:
Originally Posted by LarryChen
Also I don't really follow why you would think my cast operator can NOT be a reinterpret_cast?
Because even if you used reinterpret_cast to implement the conversion function, the fact that you specifically implemented the conversion means that the cast should be relatively safe, hence static_cast is expected.
Re: A question regarding cast operator
Quote:
Originally Posted by
laserlight
In your example, A and B are not related through inheritance. Furthermore, I did give leeway, as per the part in parentheses.
That would be completely pointless since you might as well just use dynamic_cast. (Also, see my answer concerning reinterpret_cast.)
Also, you need to be precise in your terminology. Your operator B* member is an example of a conversion function, also known as a conversion operator, but when I read "cast operator", I think of static_cast, dynamic_cast, or Boost's lexical_cast, in which case I would expect a function template from you that generically performs some kind of type coercion rather than a specific case of a conversion function.
Because even if you used reinterpret_cast to implement the conversion function, the fact that you specifically implemented the conversion means that the cast should be relatively safe, hence static_cast is expected.
First of all, it is my bad I used wrong terminology like cast operator in my last post. But I would call it conversion operator(is conversion function equivalent to conversion operator?).
Secondly, I agree it is pointless to use a convesion operator as a dynamic_cast. But why'd you think reinterpret_cast is less safe than static_cast? I think reinterpret_cast and static_cast just serve in different scenario. Thanks.
Re: A question regarding cast operator
Quote:
Originally Posted by
LarryChen
to use a convesion operator as a dynamic_cast.
In principle you can't.
A conversion operator is something you define and a dynamic_cast is defined by the language.
And see my post #5 where I explain that if you define a conversion operator you don't need to cast at all.
If you cast you're overruling the C++ type system and if you do that you're responsible for what happens. Leave it to the next guy find that strange bug. :)
Re: A question regarding cast operator
Quote:
Originally Posted by LarryChen
But I would call it conversion operator(is conversion function equivalent to conversion operator?).
Yes. Conversion function is the C++ standard's term.
Quote:
Originally Posted by LarryChen
But why'd you think reinterpret_cast is less safe than static_cast?
Because the conversion performed by reinterpret_cast is usually implementation defined, so the reader of the code has more cause to wonder if it is correct to use the cast in the first place. In the case of a conversion function, you would not even need to explicitly write the cast (but see my comment below), so the conversion is already supposed to be well defined, thus using reinterpret_cast does not make sense.
Quote:
Originally Posted by nuzzle
And see my post #5 where I explain that if you define a conversion operator you don't need to cast at all.
Unless you declare the conversion function as explicit.
Re: A question regarding cast operator
Quote:
Originally Posted by
laserlight
Unless you declare the conversion function as explicit.
Only available for C++11, unfortunately. In good old' C++98, you have to use a "proxy trick" :thumbd:
Re: A question regarding cast operator
Quote:
Originally Posted by
nuzzle
In principle you can't.
A conversion operator is something you define and a dynamic_cast is defined by the language.
And see my post #5 where I explain that if you define a conversion operator you don't need to cast at all.
If you cast you're overruling the C++ type system and if you do that you're responsible for what happens. Leave it to the next guy find that strange bug. :)
What did you mean "a dynamic_cast is defined by the language"? A even more interesting example is in the following,
Code:
class D;
class B
{
public:
operator D*();
virtual void foo(){cout<<"B"<<endl;}
};
class D : public B
{
public:
virtual void foo(){cout<<"D"<<endl;}
};
B::operator D*()
{
D* pD = dynamic_cast<D*>(this);
return pD;
}
void test(D* pD)
{
if(pD)
pD->foo();
}
int main()
{
B b;
test(b);
return 0;
}
It compiles fine but the conversion just failed. Why? Thanks.
Re: A question regarding cast operator
Quote:
Originally Posted by
LarryChen
It compiles fine but the conversion just failed. Why? Thanks.
Because your this points to a B, which is not a D.
Re: A question regarding cast operator
Quote:
Originally Posted by LarryChen
What did you mean "a dynamic_cast is defined by the language"?
That is, it is a language feature, not something you implement.
Quote:
Originally Posted by LarryChen
It compiles fine but the conversion just failed. Why?
What does dynamic_cast do? If you don't understand that, then of course you don't understand why the conversion failed.