|
Q/A
devpia.com dynamic_cast 는 RTTI 와 관련된 캐스팅 연산자입니다. 반드시 컴파일러에서 RTTI 옵션 켜셔야 하고요. 그리고 반드시 virtual 함수를 하나라도 가지고 있어야 합니다. 아니면 제대로 작동하지 않습니다. 그래서 주로 상속 관계에서 부모 클래스 포인터로 가리키고 있을 때 실제 인스턴스가 무엇인지 구분할 때 쓰는겁니다. java 의 instanceof 연산와 비슷합니다. 그에 비해 static_cast 는 좀 다릅니다.실제 인스턴스가 무엇인지 구분하는 것이 아니고 타입에 따른 엄격한 캐스팅을 하는 겁니다. 즉 C 에서의 (int*) 와 비슷하지만 좀 더 엄격한 테스팅을 하는게 다른 거지요. 그래서 반드시 캐스팅을 해야 할 경우인데 static_cast 는 쓸 수 없다면 reinterpret_cast 를 써야 합니다. 이름을 보면 아시겠지만 재해석한다라는 의미의 연산자입니다. 메모리를 타입에 맞춰 재해석해서 던져준다는 거겠지요. 실제로 C 에서의 캐스팅 연산자도 이와 유사한 의미를 가지고 있습니다. 첫번째 reinterpret_cast는 맞지 않습니다. reinterpret_cast 의 의도는 다른 포인터간에 혹은 포인터에서 정수로 등등 다른 타입간에 형변환에 사용되는것입니다. static_cast 혹은 dynamic_cast를 사용해야 하는데 장단점이 있습니다. static_cast는 C 타입의 캐스팅과 같은 기능입니다. 실제로 m_pElement변수에 CCurve의 인스턴스 포인터가 들어 있지 않다고 하더라도 캐스팅을 해줍니다. 만약 잘못된 포인터라면 프로그램에 치명적인 영향을 미칠수가 있습니다. 그러나 확실한 자식 포인터라면 오버헤드 없이 캐스팅을 할수 있습니다. dynamic_cast는 컴파일 타임이 아닌 동적을 실시간으로 형을 검사합니다. 그래서 부모클래스 혹은 자식클래스인경우는 성공적으로 형변환이 되고 아닌경우는 예전 컴파일러의 경우는 NULL로 값이 세팅되고 최신 표준을 맞춘 컴파일러는 bad_cast Exception을 발생 시킵니다. 그런데 부모자식관계과 되기 위해서는 base 클래스에서 virtual멤버를 가지고 있어야 성립이 되고 사용가능합니다. 컴파일타임이 아닌 런타임에 확인하는 관계로 오버헤드가 크므로 VC++ 같은 겨우는 디폴트로 사용이 꺼져 있습니다. 프로젝트 세팅에서 체크를 해주서야 사용 하실수 있습니다. 결론은 확실하다면 static_cast를 사용하심이 좋을것 같습니다. 그럼 ... static_cast 는 캐스팅이 가능하면 캐스팅을 합니다. 즉 완전히 다른 타입은 캐스팅이 불가능하다는 겁니다. 클래스의 경우 Base클래스와 Derived 클래스가 있고 이것이 서로 상속관계일떄 static_cast 이런것이 가능하다는 겁니다. 하지만 완전히 다른 A, B 클래스가 있을 경우(상속관계마저 없습니다.) static_cast 는 에러를 냅니다. 하지만 reinterpret_cast는 강제로 캐스팅을 해버리는거지요. 예를 들어 int형 변수를 char*형으로 캐스팅해서 int형 변수를 마치 char형 배열 4개 처럼 쓸수 있다는 겁니다. 간단히 생각하면 reinterpert -> 재 해석하다. 즉 그 변수가 차지하고 있는 변수 공간을 주어진 타입으로 재해석해버린다는 거죠. 하지만 static 은 이런 뜻 없습니다. 아래의 코드는 무슨뜻인지 설명좀 부탁합니다. m_pMainFrame = static_cast c의 캐스팅이랑 똑같이 생각하시면 됩니다.(조금 틀리긴 하지만 거의 비슷합니다.) m_pMainWnd 의 형을 CMainFrame*형으로 바꿔주는거죠. 기존의 C에 있던 cast 연산에는 몇가지 문제가 있었습니다. 예를 들어 다음과 같은 문장을 보면 Data* data = (Data*)pSomething; 여기서 쓰인 cast가 무엇인지 알수 있는 방법이 없습니다. 코드를 보는 사람뿐 아니 라 컴파일러도 알수 없겠죠. 따라서 컴파일러는 무조건 casting을 하게 됩니다. 또 한 후에 아주 긴 코드상에서 cast한 부분만을 보고자 할때도 검색어로 괄호를 넣을수 도 없고 난감하지요. 이러한 몇가지 점을 보완하고 개발자들에게 여러가지 편리함을 주고자 C++에서는 네 가지 cast operator가 정의되었습니다. static_cast, dynamic_cast, const_cast, reinterpret_cast가 그것입니다. 간단히 설명을 하자면 다음과 같습니다. static_cast - 기본적으로 기존 C에서 casting하던 것과 같은 역할을 합니다. 따 라서 기존의 C의 casting으로 안되던 것들은 이것으로도 되지 않습니다. 또한 const형을 non-const형으로 cast하는 것 역시 이 연산자로 할수 없습니다. const_cast - const형 데이터를 non-const형으로 바꾸거나 volatile형을 non- volatile형으로 cast해 줍니다. 다른 용도로는 사용할 수 없습니다. dynamic_cast - class들의 inheritance hierachy들 사이를 올바르게 cast하는 데 사용됩니다. 다른 용도로는 사용할수 없습니다. 이 기능은 RTTI(Run-time Type Information)기능을 참고하시면 도움이 되실 겁니다. 참고로 이 연산자는 올 바로 cast되지 않는 경우에는 null을 return하기 때문에 매우 유용하게 사용됩니 다. reinterpret_cast - 이 cast는 보통 구현에 따라 다르게 작업을 수행한다고 되어 있습니다. 따라서 이 연산자는 다른 컴파일러에 porting이 어렵다고 되어 있습니 다. 보통 위의 세가지 cast로 불가능한 casting을 할때 사용되며 서로 다른 프로토 타입을 가진 함수 포인터를 casting하는데 주로 사용이 됩니다. 다시 위의 예로 돌아가면 Data* data = const_cast< Data*>(pSomething); Data* data = dynamic_cast< Data*>(pSomething); Data* data = static_cast< Data*>(pSomething); 와 같은 문장이 있다면 왜 casting이 필요했는지를 쉽게 이 부분의 코드만 봐도 확인 이 되겠지요. 물론 컴파일러도 좀더 효율적이고 정확하게 컴파일이 가능할테고요. 마지막으로 C++에 관련된 책중에 여러가지 item으로 구성되어 있어서 재밌고 유용하 게 읽을수 있는 책으로 Effective C++, by Scott Meyers, Addison Wesley More Effective C++, by Scott Meyers, Addison Wesley 가 있습니다. 꼭 한번 읽어 보세요. 그냥 C++책이나 object-oriented 관련 서적 을 읽는 것과는 다른 맛(?)이 있습니다. 그럼 이만... 도움이 되셨나요.
Visual C++
방법: 다양한 문자열 형식 간 변환 이 항목에서는 다양한 ++ 문자열 형식을 다른 문자열로 변환하는 방법을 보여 줍니다. 여기에서는 char *, wchar_t*, _bstr_t, CComBSTR, CString, basic_string 및 System.String과 같은 문자열 형식을 다룹니다. 모든 경우에서 새 형식으로 변환할 때 문자열의 복사본이 만들어집니다. 새 문자열을 변경해도 원래 문자열에는 영향을 미치지 않으며, 그 반대도 마찬가지입니다. char *에서 변환 예제 설명 이 예제에서는 char *에서 위에 나열된 다른 문자열 형식으로 변환하는 방법을 보여 줍니다. 코드 코드 복사 // convert_from_char.cpp // compile with /clr /link comsuppw.lib #include #include #include #include "atlbase.h" #include "atlstr.h" #include "comutil.h" using namespace std; using namespace System; int main() { char *orig = "Hello, World!"; cout << orig << " (char *)" << endl; // Convert to a wchar_t* size_t origsize = strlen(orig) + 1; const size_t newsize = 100; size_t convertedChars = 0; wchar_t wcstring[newsize]; mbstowcs_s(&convertedChars, wcstring, origsize, orig, _TRUNCATE); wcscat_s(wcstring, L" (wchar_t *)"); wcout << wcstring << endl; // Convert to a _bstr_t _bstr_t bstrt(orig); bstrt += " (_bstr_t)"; cout << bstrt << endl; // Convert to a CComBSTR CComBSTR ccombstr(orig); if (ccombstr.Append(L" (CComBSTR)") == S_OK) { CW2A printstr(ccombstr); cout << printstr << endl; } // Convert to a CString CString cstring(orig); cstring += " (CString)"; cout << cstring << endl; // Convert to a basic_string string basicstring(orig); basicstring += " (basic_string)"; cout << basicstring << endl; // Convert to a System::String String ^systemstring = gcnew String(orig); systemstring += " (System::String)"; Console::WriteLine("{0}", systemstring); delete systemstring; } 출력 Hello, World! (char *) Hello, World! (wchar_t *) Hello, World! (_bstr_t) Hello, World! (CComBSTR) Hello, World! (CString) Hello, World! (basic_string) Hello, World! (System::String) wchar_t *에서 변환 예제 설명 이 예제에서는 wchar_t *에서 위에 나열된 다른 문자열 형식으로 변환하는 방법을 보여 줍니다. 코드 코드 복사 // convert_from_wchar_t.cpp // compile with /clr /link comsuppw.lib #include #include #include #include "atlbase.h" #include "atlstr.h" #include "comutil.h" using namespace std; using namespace System; int main() { wchar_t *orig = L"Hello, World!"; wcout << orig << L" (wchar_t *)" << endl; // Convert to a char* size_t origsize = wcslen(orig) + 1; const size_t newsize = 100; size_t convertedChars = 0; char nstring[newsize]; wcstombs_s(&convertedChars, nstring, origsize, orig, _TRUNCATE); strcat_s(nstring, " (char *)"); cout << nstring << endl; // Convert to a _bstr_t _bstr_t bstrt(orig); bstrt += " (_bstr_t)"; cout << bstrt << endl; // Convert to a CComBSTR CComBSTR ccombstr(orig); if (ccombstr.Append(L" (CComBSTR)") == S_OK) { CW2A printstr(ccombstr); cout << printstr << endl; } // Convert to a CString CString cstring(orig); cstring += " (CString)"; cout << cstring << endl; // Convert to a basic_string wstring basicstring(orig); basicstring += L" (basic_string)"; wcout << basicstring << endl; // Convert to a System::String String ^systemstring = gcnew String(orig); systemstring += " (System::String)"; Console::WriteLine("{0}", systemstring); delete systemstring; } 출력 Hello, World! (wchar_t *) Hello, World! (char *) Hello, World! (_bstr_t) Hello, World! (CComBSTR) Hello, World! (CString) Hello, World! (basic_string) Hello, World! (System::String) _bstr_t에서 변환 예제 설명 이 예제에서는 _bstr_t에서 위에 나열된 다른 문자열 형식으로 변환하는 방법을 보여 줍니다. 코드 코드 복사 // convert_from_bstr_t.cpp // compile with /clr /link comsuppw.lib #include #include #include #include "atlbase.h" #include "atlstr.h" #include "comutil.h" using namespace std; using namespace System; int main() { _bstr_t orig("Hello, World!"); wcout << orig << " (_bstr_t)" << endl; // Convert to a char* const size_t newsize = 100; char nstring[newsize]; strcpy_s(nstring, (char *)orig); strcat_s(nstring, " (char *)"); cout << nstring << endl; // Convert to a wchar_t* wchar_t wcstring[newsize]; wcscpy_s(wcstring, (wchar_t *)orig); wcscat_s(wcstring, L" (wchar_t *)"); wcout << wcstring << endl; // Convert to a CComBSTR CComBSTR ccombstr((char *)orig); if (ccombstr.Append(L" (CComBSTR)") == S_OK) { CW2A printstr(ccombstr); cout << printstr << endl; } // Convert to a CString CString cstring((char *)orig); cstring += " (CString)"; cout << cstring << endl; // Convert to a basic_string string basicstring((char *)orig); basicstring += " (basic_string)"; cout << basicstring << endl; // Convert to a System::String String ^systemstring = gcnew String((char *)orig); systemstring += " (System::String)"; Console::WriteLine("{0}", systemstring); delete systemstring; } 출력 Hello, World! (_bstr_t) Hello, World! (char *) Hello, World! (wchar_t *) Hello, World! (CComBSTR) Hello, World! (CString) Hello, World! (basic_string) Hello, World! (System::String) CComBSTR에서 변환 예제 설명 이 예제에서는 CComBSTR에서 위에 나열된 다른 문자열 형식으로 변환하는 방법을 보여 줍니다. 코드 코드 복사 // convert_from_ccombstr.cpp // compile with /clr /link comsuppw.lib #include #include #include #include "atlbase.h" #include "atlstr.h" #include "comutil.h" #include "vcclr.h" using namespace std; using namespace System; using namespace System::Runtime::InteropServices; int main() { CComBSTR orig("Hello, World!"); CW2A printstr(orig); cout << printstr << " (CComBSTR)" << endl; // Convert to a char* const size_t newsize = 100; char nstring[newsize]; CW2A tmpstr1(orig); strcpy_s(nstring, tmpstr1); strcat_s(nstring, " (char *)"); cout << nstring << endl; // Convert to a wchar_t* wchar_t wcstring[newsize]; wcscpy_s(wcstring, orig); wcscat_s(wcstring, L" (wchar_t *)"); wcout << wcstring << endl; // Convert to a _bstr_t _bstr_t bstrt(orig); bstrt += " (_bstr_t)"; cout << bstrt << endl; // Convert to a CString CString cstring(orig); cstring += " (CString)"; cout << cstring << endl; // Convert to a basic_string wstring basicstring(orig); basicstring += L" (basic_string)"; wcout << basicstring << endl; // Convert to a System::String String ^systemstring = gcnew String(orig); systemstring += " (System::String)"; Console::WriteLine("{0}", systemstring); delete systemstring; } 출력 Hello, World! (CComBSTR) Hello, World! (char *) Hello, World! (wchar_t *) Hello, World! (_bstr_t) Hello, World! (CString) Hello, World! (basic_string) Hello, World! (System::String) CString에서 변환 예제 설명 이 예제에서는 CString에서 위에 나열된 다른 문자열 형식으로 변환하는 방법을 보여 줍니다. 코드 코드 복사 // convert_from_cstring.cpp // compile with /clr /link comsuppw.lib #include #include #include #include "atlbase.h" #include "atlstr.h" #include "comutil.h" using namespace std; using namespace System; int main() { CString orig("Hello, World!"); wcout << orig << " (CString)" << endl; // Convert to a char* const size_t newsize = 100; char nstring[newsize]; strcpy_s(nstring, orig); strcat_s(nstring, " (char *)"); cout << nstring << endl; // Convert to a wchar_t* // You must first convert to a char * for this to work. size_t origsize = strlen(orig) + 1; size_t convertedChars = 0; wchar_t wcstring[newsize]; mbstowcs_s(&convertedChars, wcstring, origsize, orig, _TRUNCATE); wcscat_s(wcstring, L" (wchar_t *)"); wcout << wcstring << endl; // Convert to a _bstr_t _bstr_t bstrt(orig); bstrt += " (_bstr_t)"; cout << bstrt << endl; // Convert to a CComBSTR CComBSTR ccombstr(orig); if (ccombstr.Append(L" (CComBSTR)") == S_OK) { CW2A printstr(ccombstr); cout << printstr << endl; } // Convert to a basic_string string basicstring(orig); basicstring += " (basic_string)"; cout << basicstring << endl; // Convert to a System::String String ^systemstring = gcnew String(orig); systemstring += " (System::String)"; Console::WriteLine("{0}", systemstring); delete systemstring; } 출력 Hello, World! (CString) Hello, World! (char *) Hello, World! (wchar_t *) Hello, World! (_bstr_t) Hello, World! (CComBSTR) Hello, World! (basic_string) Hello, World! (System::String) basic_string에서 변환 예제 설명 이 예제에서는 basic_string에서 위에 나열된 다른 문자열 형식으로 변환하는 방법을 보여 줍니다. 코드 코드 복사 // convert_from_basic_string.cpp // compile with /clr /link comsuppw.lib #include #include #include #include "atlbase.h" #include "atlstr.h" #include "comutil.h" using namespace std; using namespace System; int main() { string orig("Hello, World!"); cout << orig << " (basic_string)" << endl; // Convert to a char* const size_t newsize = 100; char nstring[newsize]; strcpy_s(nstring, orig.c_str()); strcat_s(nstring, " (char *)"); cout << nstring << endl; // Convert to a wchar_t* // You must first convert to a char * for this to work. size_t origsize = strlen(orig.c_str()) + 1; size_t convertedChars = 0; wchar_t wcstring[newsize]; mbstowcs_s(&convertedChars, wcstring, origsize, orig.c_str(), _TRUNCATE); wcscat_s(wcstring, L" (wchar_t *)"); wcout << wcstring << endl; // Convert to a _bstr_t _bstr_t bstrt(orig.c_str()); bstrt += " (_bstr_t)"; cout << bstrt << endl; // Convert to a CComBSTR CComBSTR ccombstr(orig.c_str()); if (ccombstr.Append(L" (CComBSTR)") == S_OK) { CW2A printstr(ccombstr); cout << printstr << endl; } // Convert to a CString CString cstring(orig.c_str()); cstring += " (CString)"; cout << cstring << endl; // Convert to a System::String String ^systemstring = gcnew String(orig.c_str()); systemstring += " (System::String)"; Console::WriteLine("{0}", systemstring); delete systemstring; } 출력 Hello, World! (basic_string) Hello, World! (char *) Hello, World! (wchar_t *) Hello, World! (_bstr_t) Hello, World! (CComBSTR) Hello, World! (CString) Hello, World! (System::String) System::String에서 변환 예제 설명 이 예제에서는 System.String에서 위에 나열된 다른 문자열 형식으로 변환하는 방법을 보여 줍니다. 코드 코드 복사 // convert_from_system_string.cpp // compile with /clr /link comsuppw.lib #include #include #include #include "atlbase.h" #include "atlstr.h" #include "comutil.h" #include "vcclr.h" using namespace std; using namespace System; using namespace System::Runtime::InteropServices; int main() { String ^orig = gcnew String("Hello, World!"); Console::WriteLine("{0} (System::String)", orig); pin_ptr // Convert to a char* size_t origsize = wcslen(wch) + 1; const size_t newsize = 100; size_t convertedChars = 0; char nstring[newsize]; wcstombs_s(&convertedChars, nstring, origsize, wch, _TRUNCATE); strcat_s(nstring, " (char *)"); cout << nstring << endl; // Convert to a wchar_t* wchar_t wcstring[newsize]; wcscpy_s(wcstring, wch); wcscat_s(wcstring, L" (wchar_t *)"); wcout << wcstring << endl; // Convert to a _bstr_t _bstr_t bstrt(wch); bstrt += " (_bstr_t)"; cout << bstrt << endl; // Convert to a CComBSTR CComBSTR ccombstr(wch); if (ccombstr.Append(L" (CComBSTR)") == S_OK) { CW2A printstr(ccombstr); cout << printstr << endl; } // Convert to a CString CString cstring(wch); cstring += " (CString)"; cout << cstring << endl; // Convert to a basic_string wstring basicstring(wch); basicstring += L" (basic_string)"; wcout << basicstring << endl; delete orig; } 출력 Hello, World! (System::String) Hello, World! (char *) Hello, World! (wchar_t *) Hello, World! (_bstr_t) Hello, World! (CComBSTR) Hello, World! (CString) Hello, World! (basic_string) 참고 항목 작업 방법: 표준 문자열을 System::String으로 변환 방법: System::String을 표준 문자열로 변환 방법: System::String을 wchar_t* 또는 char*로 변환 참조 mbstowcs_s, _mbstowcs_s_l wcstombs_s, _wcstombs_s_l strcpy_s, wcscpy_s, _mbscpy_s strcat_s, wcscat_s, _mbscat_s pin_ptr 개념 ATL and MFC String Conversion Macros CString Operations Relating to C-Style Strings Programming with CComBSTR 기타 리소스 Visual C++ 둘러보기
http://www.codeproject.com/win32/cjbcontrolpanelapplet.asp
http://www.codeproject.com/system/controlpanel.asp http://www.codeproject.com/shell/cpl.asp
Recent versions of the Qt library source give errors on compilation:
A fix to the VC++ compiler has caused certain template code not to compile with Visual Studio 2005 SP1 and to give a C2244 error. The code that does compiles without SP1 uses inherited template classes and nested types. In particular, current versions of the Qt library source that use such template code are affected by this change. The most basic form of the problematic code looks like this:template class A { public: typedef int N_A; }; template class B : public A { public: typename A }; template typename A { return 0; } Template class B inherits from template class A. A class A { public: typedef int N_A; }; template class B : public A { public: typedef A typename N_B test(); // use of the typedef in the return type }; template typename B { return 0; }
|
![]() by 내맘 카테고리
이전블로그
이글루링크
최근 등록된 덧글
| |||