|
Robert Edward Caldecott wrote: I can't believe I haven't come across the x = type(y); syntax before
default constructors...
TOXCCT >>> GEII power
[VisualCalc 3.0 updated ][Flags Beginner's Guide new! ]
|
|
|
|
|
They are syntactically the same. It's much like:
int foo( void )
{
return 12;
} vs.
int foo( void )
{
return (12);
} Some folks use parenthesis with the sizeof operator:
int x = sizeof(obj); while others do not:
int x = sizeof obj;
"Money talks. When my money starts to talk, I get a bill to shut it up." - Frank
"Judge not by the eye but by the heart." - Native American Proverb
|
|
|
|
|
In this case it is the same thing, but in general the syntax you describe is not casting, but initialization.
On the other hand, I like to use C++ casts (static_cast, reinterpret_cast) these days. It is very easy to search for them in the code, unlike the C style casts.
My programming blahblahblah blog. If you ever find anything useful here, please let me know to remove it.
|
|
|
|
|
Nemanja Trifunovic wrote: On the other hand, I like to use C++ casts (static_cast, reinterpret_cast) these days.
Me too, usually - however, when casting POD types like this, is there really any benefit from using static_cast ?
|
|
|
|
|
Hmm, for some reason it put my post as a reply to the wrong original post...
DavidCrow wrote: Some folks use parenthesis with the sizeof operator:
int x = sizeof(obj);
while others do not:
int x = sizeof obj;
Actually, sizeof expr does not need parentheses, but sizeof(type) requires them (you can check the C++ grammar). I get a compile error when trying to compile this program:
#include <iostream>
int main()
{
int i = 0;
std::cout << sizeof(i) << '\n';
std::cout << sizeof i << '\n';
std::cout << sizeof(int) << '\n';
std::cout << sizeof int << '\n';
}
--
Marcus Kwok
-- modified at 17:16 Monday 17th July, 2006
|
|
|
|
|
Robert Edward Caldecott wrote: when casting POD types like this, is there really any benefit from using static_cast?
With integral types, and classes/structs without a constructor/destructor, there's no benefit.
"Money talks. When my money starts to talk, I get a bill to shut it up." - Frank
"Judge not by the eye but by the heart." - Native American Proverb
|
|
|
|
|
I stand corrected. I always use parenthesis, regardless of the object, so I've never seen this compiler error. Thanks.
"Money talks. When my money starts to talk, I get a bill to shut it up." - Frank
"Judge not by the eye but by the heart." - Native American Proverb
|
|
|
|
|
Yes there is, visability and clarity.
Steve
|
|
|
|
|
I get the same benefit(s) from C-style casts. It's very clear to me what they are doing. If casting errors are something that a person is prone to making, having the compiler warn of impending danger might be a benefit.
"Money talks. When my money starts to talk, I get a bill to shut it up." - Frank
"Judge not by the eye but by the heart." - Native American Proverb
|
|
|
|
|
C style casts are anything but clear. While C-style casts look simple they are actually very complicated and subtle. In small programs this often goes unnoticed. But as the program gets larger real problems can and do occur. Try this example program. I know it's on the longish side but it's typical of real applications and may suprise you.
The output with the #include is:
Base2
The output without #include is:
Base1
Not many C++ programmers will be able to spot the problem.
--------------------
// Casts.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <iostream>
#include "Functions.h"
// C-style casts suck. The program will compile with or without the line below using C-style casts.
// With it all is OK, without it the program misbehaves at runtime. If 'static_cast' is used the
// program not compile without the #include and you don't get any nasty suprises.
#include "Classes.h"
int main(int argc, char* argv[])
{
Derived *pDerived = MakeDerived();
DoStuff((Base2*)pDerived);
//DoStuff(static_cast<Base2*>(pDerived));
KillDerived(pDerived);
return 0;
}
\/\/\/\/\/\/
// Classes.h
#ifndef __CLASSES_H__
#define __CLASSES_H__
class Base1
{
public:
Base1();
void Print() const;
private:
const char *m_pName;
};
class Base2
{
public:
Base2();
void Print() const;
private:
const char *m_pName;
};
class Derived : public Base1, public Base2
{
};
#endif // !__CLASSES_H__
\/\/\/\/\/\/
// Functions.h
#ifndef __FUNCTIONS_H__
#define __FUNCTIONS_H__
class Base1;
class Base2;
class Derived;
Derived* MakeDerived();
void KillDerived(Derived *pDerived);
void DoStuff(Base2 *pB2);
#endif // !__FUNCTIONS_H__
\/\/\/\/\/\/
// Implementation.cpp
#include "stdafx.h"
#include "Functions.h"
#include "Classes.h"
#include <iostream>
Base1::Base1()
{
m_pName = "Base1";
}
void Base1::Print() const
{
using namespace std;;
cout << m_pName << endl;
}
Base2::Base2()
{
m_pName = "Base2";
}
void Base2::Print() const
{
using namespace std;;
cout << m_pName << endl;
}
Derived* MakeDerived()
{
return new Derived;
}
void KillDerived(Derived *pDerived)
{
delete pDerived;
}
void DoStuff(Base2 *pB2)
{
pB2->Print();
}
Steve
|
|
|
|
|
in C++ you can (should?) use the static_cast; it takes a little longer to type, but I think it makes casting a lot more clearer.
long aLong = 1234L;
short aShort = static_cast<short>( aLong );
Maximilien Lincourt
Your Head A Splode - Strong Bad
|
|
|
|
|
Maximilien wrote: short aShort = static_cast( aLong );
you meant short aShort = static_cast<short>( aLong ); i believe
TOXCCT >>> GEII power
[VisualCalc 3.0 updated ][Flags Beginner's Guide new! ]
|
|
|
|
|
darn, I forgot the <> get zapped by default.
Maximilien Lincourt
Your Head A Splode - Strong Bad
|
|
|
|
|
Maximilien wrote: I forgot the <> get zapped by default.
The angle brackets are there, just hidden.
"Money talks. When my money starts to talk, I get a bill to shut it up." - Frank
"Judge not by the eye but by the heart." - Native American Proverb
|
|
|
|
|
Robert Edward Caldecott wrote: I can't believe I haven't come across the x = type(y); syntax before. I asked some other C/C++ old-timers here and they hadn't seen it either. Mad. Always something new to learn!
I use it all the time. I use that syntax because it looks like a constructor, rather than a cast. Easier to type than static_cast, and just as easy to search for as static_cast. It's a bit dangerous, as it works like a reinterpret_cast, but hey! I've grown up, and I don't need mommy to hold my hand. (Lots of drugs are required before I start casting HANDLEs to BYTEs, etc. Since I don't use drugs, I don't worry much about bad casts. )
--
80 percent entertainment by volume
|
|
|
|
|
Jörgen Sigvardsson wrote: I've grown up, and I don't need mommy to hold my hand. (Lots of drugs are required before I start casting HANDLEs to BYTEs, etc. Since I don't use drugs, I don't worry much about bad casts. )
You may have grown up, but I can almost guarantee that 1) you won't be working at the same place forever 2) some knucklehead will come in and think he can safely cast anything to anything and use your code as an example and 3) you will find out that not using the C++-style casts will create an inconsistent coding style in your developments.
Just an FYI.
If you decide to become a software engineer, you are signing up to have a 1/2" piece of silicon tell you exactly how stupid you really are for 8 hours a day, 5 days a week
Zac
|
|
|
|
|
Zac Howland wrote: some knucklehead will come in and think he can safely cast anything to anything and use your code as an example
This is the wisest thing I've heard on CP for some time; I agree completely.
Steve
|
|
|
|
|
Stephen Hewitt wrote: This is the wisest thing I've heard on CP for some time; I agree completely.
Thank you. That statement comes from years of watching that exact situation occur time and time again.
If you decide to become a software engineer, you are signing up to have a 1/2" piece of silicon tell you exactly how stupid you really are for 8 hours a day, 5 days a week
Zac
|
|
|
|
|
Zac Howland wrote: 2) some knucklehead will come in and think he can safely cast anything to anything and use your code as an example
I think casts would be the least of this knuckleheads's troubles if he doesn't understand how casts work in C++.
Zac Howland wrote: you will find out that not using the C++-style casts will create an inconsistent coding style in your developments.
Yes, and no. If I start mixing the casts, then it'd be inconsistent. I use C++ casts to indicate that something worth paying attention to is happening. For instance - downcasts (static_cast), round-ball-into-square-hole-casts (reinterpret_cast), and dynamic casts (dynamic_cast). In essence, I only to constructor like casts when dealing with integral types. In that code, it's obvious what's going on - no need to pollute the visibility with lots of text.
My 2 cents.
--
As Foretold by NostradamusLast modified: den 17 juli 2006 20:09:40 --
|
|
|
|
|
Jörgen Sigvardsson wrote: In essence, I only to constructor like casts when dealing with integral types.
I have used these types of casts for integral types myself; however, I tend to look at them more as constructors instead of casts. For example:
long l = 1234L;
short s = (short)l;
Is really just creating a short by "passing" a long into an implicitly overriden constructor. It is easier to see if you view it as objects instead of primitive types. In that sense, I agree with you, but I still use caution when doing it for one simple reason: many beginning programmers tend to be lazy and see the above code and think nothing of extending it to do the following:
class A {};
class B : public A {};
B b;
B* pB = &b;
A* pA = (A*)pB;
Which while safe in this example, can get much more complex with a different inheritance model.
If you decide to become a software engineer, you are signing up to have a 1/2" piece of silicon tell you exactly how stupid you really are for 8 hours a day, 5 days a week
Zac
|
|
|
|
|
The cast long l = 1234L; short s = (short)l; is equivalent to long l = 1234L; short s = short(l); . There is absolutely no difference between them and no advantage for using 1 over another.
That said, in C++, you should always try to cast using the proper C++-style casting operator (dynamic_cast, static_cast, const_cast, reinterpret_cast, etc.) See "Effective C++" by Scott Meyers for both why to use them and which ones to use when (and which ones to avoid using).
If you decide to become a software engineer, you are signing up to have a 1/2" piece of silicon tell you exactly how stupid you really are for 8 hours a day, 5 days a week
Zac
|
|
|
|
|
Anyone have an idea how to find the RGB value of the default MFC dialog.
I am building a program and need to know what color the screen comes up as so that after I am done using the CDC->TextOut command, I can call it again with a font of the same color as the background.
Please advise.
Thank you.
|
|
|
|
|
Well, I believe that the background color is GetSysColor(COLOR_3DFACE), as long as XP Visual Styles don't come into play -- they it could be anything, including a bitmap.
You would be better served to just call dc->SetBkMode(TRANSPARENT) and just draw transparent text.
|
|
|
|
|
I was using the SetBkMode(Transparent) call, but I wanted to be able to find the color of the background so that I could clean up the screen by simply calling the same TextOut function, but with the background color to effectively "mask" away the text I already painted. The GetSysColor function seems to be working. Thanks for the information.
|
|
|
|
|
See GetBkColor(GetDC()->m_hDC)
whitesky
|
|
|
|