Auto Attach 디버깅 툴(Visual Studio)

Game Programming/C++ 2019. 4. 16. 15:13

설정

트랙백

댓글

생성자/파괴자 내부에서 virtual 함수 사용이 안되는(virtual 대신 일반 함수처럼 동작됨) 이유

Game Programming/C++ 2018. 3. 8. 07:18

https://stackoverflow.com/questions/962132/calling-virtual-functions-inside-constructors

https://isocpp.org/wiki/faq/strange-inheritance#calling-virtuals-from-ctors

1 . 생성자에서 부를 때 명확한 예

  1. #include<string>
  2. #include<iostream>
  3. using namespace std;
  4. class B {
  5. public:
  6. B(const string& ss) { cout << "B constructor\n"; f(ss); }
  7. virtual void f(const string&) { cout << "B::f\n";}
  8. };
  9. class D : public B {
  10. public:
  11. D(const string & ss) :B(ss) { cout << "D constructor\n";}
  12. void f(const string& ss) { cout << "D::f\n"; s = ss; }
  13. private:
  14. string s;
  15. };
  16. int main()
  17. {
  18. D d("Hello");
  19. }

결과

  1. B constructor
  2. B::f
  3. D constructor


만일 B::f 대신 D::f 를 허용한다면 D constructor 호출 이전이므로

s = ss; 에서 초기화되지 않은 string s 를 사용해야하므로 crash 가 발생할 수 있다.

 C++ is protecting you from that danger. 의 차원에서 허용되지 않는다고 볼 수 있다.


2. 파괴자에서는 생성자 호출 순서의 역순으로 수행되므로

위의 클래스 예를 들어보면 D 의 파괴자 호출 후에 B 파괴자가 호출된다.

B 파괴자 내부에서 f(ss); 를 호출하여 D::f 를 호출 한다는 것도 성립할 수 없게 된다.(만일 D::f 가 호출된다면 이미 파괴된 string s 를 참조하려고 한다.)


설정

트랙백

댓글

여러 폰트를 사용중 같은 위치에 출력하고 싶을때 !!!

Game Programming/C++ 2011. 12. 9. 22:08

47.4 How can I draw a single line of text with different fonts using DrawString?

   

The key is that you have to calculate the ascent height of the font. The font ascent as reported by FontFamily.GetCellAscent is in what is called 'Design Units'. The Cell Spacing design unit value of fonts is proportional to the actual height of the font on the device. We use this relationship to calculate cell ascent in device units.

The rendering code has to just ensure that the x, y position passed to DrawString takes care of the ascent.

     private void HandlePaint(object sender, PaintEventArgs args) 
     { 
          // clear the background 
          Graphics g = args.Graphics; 
          g.Clear(Color.AliceBlue); 
           
          // create a pen 
          Pen pen = new Pen(Color.Red, 1f); 
           
          // the string to be drawn 
          string s = "Side by side"; 
           
          // the first font 
          Font f1 = new Font("Arial", 10f); 
          float strWidth1 = g.MeasureString(s, f1).Width; 
          float fontHeight1 = f1.GetHeight(g);      
          float fontAscentHeight1 = (fontHeight1/f1.FontFamily.GetLineSpacing(f1.Style))*f1.FontFamily.GetCellAscent(f1.Style); 
                
          // the second font 
          Font f2 = new Font("Times New Roman", 48); 
               float fontHeight2 = f2.GetHeight(g);      
               float fontAscentHeight2 = (fontHeight2/f2.FontFamily.GetLineSpacing(f2.Style))*f2.FontFamily.GetCellAscent(f2.Style); 

          // draw the base line      
          Point ptStart = new Point(0, this.ClientSize.Height/2); 
          Point ptEnd = new Point(this.ClientSize.Width, this.ClientSize.Height/2); 
          g.DrawLine(Pens.Black, ptStart, ptEnd); 
      
          // draw string with first font 
          g.DrawString(s, f1, Brushes.Red, new PointF(0, ptStart.Y - fontAscentHeight1)); 
          // draw string with second font 
          g.DrawString(s, f2, Brushes.Red, new PointF(strWidth1, ptStart.Y - fontAscentHeight2)); 
     }

참고 : http://msdn.microsoft.com/en-us/library/xwf9s90b.aspx
출처 : http://www.syncfusion.com/FAQ/windowsforms/faq_c39c.aspx 

설정

트랙백

댓글

Visual Studio 유용한 정규식 패턴

Game Programming/C++ 2011. 6. 14. 18:54

  • ".*[가-힣]+.*" : 한글이 하나이상 포함되어 있는 문자열 선택
  • visual studio 에서 찾아 바꾸기 정규식 사용시 () 태깅한 텍스트는 바꾸기 에서 $n 으로 대응됨. (n 은 1 에서 9가 들어갈수 있으며 0을 입력하면 전체를 의미함)

     ex ) UE_LOG(Log, 로 시작하고
    찾을 내용:
    UE_LOG\(Log, ([\s\w\d,]+)TEXT\(\"([\s\w\d-_\(\)\[\]%*.,:=!]+)\"\)
    바꿀 내용:
    LOG($1"$2"



  • msdn :  https://msdn.microsoft.com/ko-kr/library/2k3te2cs.aspx 참고


설정

트랙백

댓글

C++ 매크로를 호출할때 인수로 함수를 사용할 경우 매크로 본문에 주의하자.

Game Programming/C++ 2010. 8. 26. 16:06
// inline_functions_macro.c
#include <stdio.h>
#include <conio.h>

#define toupper(a) ((a) >= 'a' && ((a) <= 'z') ? ((a)-('a'-'A')):(a))

int main() {
   char ch;
   printf_s("Enter a character: ");
   ch = toupper( getc(stdin) );
   printf_s( "%c", ch );
}

위 코드를 수행할 때
매크로를 호출할때 인수로 함수를 넘기면,
a >= 'a' 를 확인하기위해 getc 한번 호출되고
a <= 'z' 를 확인하기 위해 한번더 호출되고,
((a)-('a'-'A')):(a)) 를 하기 위해 한번더 호출되어
아래와 같은 결과를 출력한다.

Sample Input: xyz

Sample Output: Z
이때는 inline 을 사용하여 해결하자 !!!

// inline_functions_inline.cpp
#include <stdio.h>
#include <conio.h>

inline char toupper( char a ) {
   return ((a >= 'a' && a <= 'z') ? a-('a'-'A') : a );
}

int main() {
   printf_s("Enter a character: ");
   char ch = toupper( getc(stdin) );
   printf_s( "%c", ch );
}

Sample Input: a

Sample Output: A
출처 : MSDN
http://msdn.microsoft.com/en-us/library/bf6bf4cf.aspx

설정

트랙백

댓글

VC++ Version Stamping

Game Programming/C++ 2010. 7. 12. 14:47
http://msdn.microsoft.com/en-us/library/cc194812.aspx

Version Stamping

Glossary

  • Version stamp: In Windows, the information included in the resource file that specifies the company name, application name, copyright, version number, and language edition of a program.

A special resource type, the version stamp can be used to declare which language or languages a given executable or DLL supports. A setup program can check this stamp to ensure, for example, that it installs the correct language edition of a file. Programs can also access the version stamp at run time to verify which language resources are contained in available files.

The following excerpt is from a Win32 version stamp that includes both English and German translations.

#define VER_FILEDESCRIPTION_STR_USA "Sample"
#define VER_FILEDESCRIPTION_STR_GER "Beispielanwendung"

#define VER_PRODUCTNAME_STR_USA \
"Sample\256"
#define VER_PRODUCTNAME_STR_GER \
"Beispielanwendung\256"

#define VER_INTERNALNAME_STR "Sample"
#define VER_ORIGINALFILENAME_STR "SAMPLE.EXE"
#define VER_PRODUCTVERSION_STR "1.65"

#define VER_LEGALCOPYRIGHT_YEARS "1991-1993"
#define VER_LEGALCOPYRIGHT_STR \
"Copyright \251 XYZ Corp." VER_LEGALCOPYRIGHT_YEARS


#define VER_FILEVERSION VER_PRODUCTVERSION
#define VER_COMPANYNAME_STR "XYZ Corp."


VS_VERSION_INFO VERSIONINFO
FILEVERSION VER_FILEVERSION
PRODUCTVERSION VER_PRODUCTVERSION
FILEFLAGSMASK VER_FILEFLAGSMASK
FILEFLAGS VER_FILEFLAGS
FILEOS VER_FILEOS
FILETYPE VER_FILETYPE
FILESUBTYPE VER_FILESUBTYPE
BEGIN
BLOCK "StringFileInfo"
BEGIN
BLOCK "040904B0" /* LANG_ENGLISH/SUBLANG_ENGLISH_US,
Unicode CP */
BEGIN
VALUE "CompanyName", VER_COMPANYNAME_STR
VALUE "FileDescription", VER_FILEDESCRIPTION_STR
VALUE "InternalName", VER_INTERNALNAME_STR
VALUE "LegalCopyright", VER_LEGALCOPYRIGHT_STR
VALUE "OriginalFilename", VER_ORIGINALFILENAME_STR
VALUE "ProductName", VER_PRODUCTNAME_STR_USA
END

BLOCK "040704B0" /* LANG_GERMAN/SUBLANG_DEFAULT, Unicode CP */
BEGIN
VALUE "CompanyName", VER_COMPANYNAME_STR
VALUE "FileDescription", VER_FILEDESCRIPTION_STR
VALUE "InternalName", VER_INTERNALNAME_STR
VALUE "LegalCopyright", VER_LEGALCOPYRIGHT_STR
VALUE "OriginalFilename", VER_ORIGINALFILENAME_STR
VALUE "ProductName", VER_PRODUCTNAME_STR_GER
END
END

BLOCK "VarFileInfo"
BEGIN
VALUE "Translation", 0x04B0, 0x0409L, 0x04B0, 0x0407L 
/* Unordered list of Lang IDs and their code page IDs 
(Unicode = 1200 in case of Win32). These can be
expressed using either hexadecimal or decimal. */
END
END

Note that each language ID appears at the beginning of a StringFileInfo block (to specify the language of the strings in the block of information) and at the end in the Translation field of the VarFileInfo block. The Translation field is a variable-length list of language IDs that indicates that resources in these different languages are available to the application. In the Visual C++ 2 editing environment, adding a new string block is a simple matter of clicking the mouse button on the right while editing a version resource, as shown below.

The following sample illustrates how an application might use version stamp information. Programs can call the function VerInstallFile to replace files on a hard disk with newer versions from installation disks. The function compares all language IDs in the Translation information of the source with all language IDs in the Translation information of the destination. The comparison is done in random order. If the language information in the new file does not match the language information of the file it is replacing, VerInstallFile returns an error code.

TCHAR szTemp[_MAX_PATH];
DWORD len = _MAX_PATH;
DWORD rc = VerInstallFile( NULL,
L"GER.DLL", // file to install
L"GER.DLL", // new name of file to install
L"A:\\LANGS\\", // source directory
L"C:\\APP\\", // installation directory
L"C:\\OLD", // existing version of file
szTemp,
&dwLen);
if (rc & VIF_DIFFLANG) 
{
<languages differ>
}
else
{
<proceed>
}

Programs can also compare the version information in a DLL with version information contained in a corresponding EXE to make sure that the correct version of the DLL is installed on the user's computer. In general, when you have the option, choose a DLL that has the correct version number over one that supports a particular language. After all, without the correct version of a DLL, your program probably won't work properly.

설정

트랙백

댓글

STL 연관 컨테이너(예제: multimap) erase 시 주의 사항!!

Game Programming/C++ 2010. 6. 21. 18:28
STL 연관 컨테이너를 사용하다 보면 아래와 같이 사용하는 경우가 있다.

typedef multimap<int, std::string> _TESTList;

_TESTList lst;
_TESTList::iterator it;
pair< _TESTList::iterator, _TESTList::iterator > range;

for(int i = 0; i < 5; i++)
lst.insert(make_pair(i * 10, "test"));

for(int i = 0; i < 5; i++)
{
lst.insert(make_pair(35, "test35"));
if(i == 3)
lst.insert(make_pair(35, "erase target"));
}

cout << "org : " << endl;
for(it = lst.begin(); it != lst.end(); it++)
cout << it->first << ", " << it->second.c_str() << endl;
cout << "erase 35" << endl;
range = lst.equal_range(35);
for (it = range.first; it != range.second; it++)
{
if( it->second.compare("erase target") == 0 )
lst.erase( it );
}

cout << "after : " << endl;
for(it = lst.begin(); it != lst.end(); it++)
cout << it->first << ", " << it->second.c_str() << endl;

붉은색 하이라이트 부분을 보면 range 를 탐색하며 "erase target"과 동일한
멤버를 찾아 삭제하고 있다. 이대로 실행하면 컴파일러가 에러를 뱉는다.

이유는 it 가 가리키는 요소를 지워 it 가 무효화 되어 it++ 를 수행할 수 없게된다.

아래와 같이 고치면 해결할 수 있다.

<해결 1>
for (it = range.first; it != range.second; )
{
if( it->second.compare("erase target") == 0 )
lst.erase( it++ );
else
it++;
}

<해결 2>
for (it = range.first; it != range.second; )
{
if( it->second.compare("erase target") == 0 )
it = lst.erase( it );
else
it++;
}



설정

트랙백

댓글

SIZE_OF_ARRAY

Game Programming/C++ 2010. 5. 20. 14:56

1. #define SIZE_OF_ARRAY(x) (sizeof(x) / sizeof(x[0]))
2. _countof() 

설정

트랙백

댓글