2022. 7. 27. 10:50

this.KeyPreview = true;

 

이것을 Load 함수에서 호출하면 바로 키보드가 먹는다

 

이거 때문에 개고생에서 시간을 오래 끌었다

2022. 5. 20. 09:47

다음의 코드로 다 설명이 된다

 

2021. 8. 18. 14:28

CApple* pApple;

pApple->Show( );

 

다음과 같은 경우 발생한다

 

참조되지 않은 포인터, 즉 정확한 메모리 위치를 가리키지 않고 사용할 때  발생한다

 

또는 다음과 같은 경우도 있다

 

CApple* pApple = new CApple( );

// pApple 사용

 

delete pApple;

pApple->Show( );

 

위와 같은 경우도 마찬가지이다

 

일반적인 프로그램에서도 먼저 포인터를 삭제한 후 

다른 곳에서 갖다 쓸 때 발생하는 에러이다.

 

CAppleDlg::CAppleDlg( )

{

    m_pApple = new CApple( );

}

 

CAppleDlg::~CAppleDlg( )

{

    delete m_pApple;

}

 

CAppleUse::Process( )

{

    CAppleDlg dlg;

    m_pApple = dlg.GetApple( );

}

 

CAppleUse::Select( )

{

    m_pApple->Show( ); // 0xC0000005 오류 발생, 이미 ~CAppleDlg( )에서 객체 삭제

}

 

 

 

2021. 1. 19. 11:04

ERROR C7525 인라인 변수에는 '/std:c++17' 이상이 필요합니다


Visual Stuidio 2019를 사용해서 빌드하는데 갑자기 저런 오류가 뜬다


이유는 C++ 언어 표준이 IST C++14 표준으로 되어 있기 때문에다


이런 경우는 ISO C++17 표준으로 설정하던지


미리보기 - 최신 C++ 초안의 기능(/std:c++latest) 로 설정하면 된다


왜 Visual Studio 2019인데 C++17로 설정을 안 했는지


또는 최신으로 설정 안 하고 IST C++14로 설정했는지는 모르겠다



2021. 1. 19. 10:32

도구 - 옵션 - 텍스트 편집기 - C/C++ - 탭 - 탭 유지 대신 공백 삽입

2020. 11. 20. 15:32

변수를 사용하는 부분에 있어서 가능하면 const를 사용하라


int i = 10;

for(int j = 0; j < i; ++j)

{

    ++i;

}



무한 루프로 돌아 논리 상의 버그이다 


하지만 const int i = 10; 으로 선언하면 코드 오류이기 때문에 컴파일러가 

잡아낸다


따라서 가능한 많은 경우에 const를 사용하자




explicit Annotation(const string text)

 : value(move(text))

{

}



위의 코드는 에러가 난다


value에 text를 넣는데 text를 넣고 move를 하면 text에는 nullptr이 들어가는데


const로 되어 있기 때문에 변경이 안 된다


위와 같은 경우는 const를 삭제해야 한다




template <typename T>

void swap(T& a, T& b) {

    T tmp(a);

    a = b;

    b = tmp;

}



위의 코드보다는 아래의 코드가 훨씬 효율적이다



template <typename T>

void swap(T& a, T& b) {

    T tmp(std::move(a));

    a = std::move(b);

    b = std::move(tmp);

}





2020. 11. 19. 15:53

C++ 11 항목

프로그래밍/C++ 2020. 11. 19. 15:53

auto


변수의 자료형을 컴파일 시간에 자동으로 추론


선언시 추론된 형은 종료시까지 사용됨


대입시 자료현 변경이 안 됨


auto a = 10;   // int


auto b = 1.0f;  // float


auto c = 1.0;   // double


auto d = "abc"; // char* 


auto e = {1, 2, 3}; // std::initializer_list


auto f = { 10 }; // c++ 14까지는 std::initializer_list, c++17 부터는 int


auto g { 10 }; // int


g = 12.34;   // warning C4244: '=' 데이터 손실


string h = { "abc" };


auto i = h.begin( ); // std::string::iterator

    

    

vector<int> v = {1,2,3,4,5};

//auto 키워드를 사용한 전 vector를 순회하는 반복자의 선언

for (intVector::iterator it = v.begin(); it != v.end(); ++it) {

    cout << *it << endl;

}


//auto 키워드를 사용한 후 vector를 순회하는 반복자 선언

for (auto it = v.begin(); it != v.end(); ++it) {

    cout << *it << endl;

}


//auto 키워드를 이용한 for loop 

for (auto& value : v) {

    cout << value << endl;

}




value category ( 값 유형 )


값의 분류 기준


값이 식별성을 갖고 있는가?


값이 메모리에서 이동할 수 있는가?


(gl-value, pr-value, x-value, l-value, r-value)


       값 유형              값이 메모리에서 이동      값이 메모리에서 이동 X



값이 식별성을 가질 때      x - value                   l - value           gl-value



값이 식별성이 없을 때      pr-value

   (임시 변수)


                                r-value




int && c = 10;


r-value를 참조하는 연산자



decltype


현재 변수나 표현식의 타입을 알아낼 수 있는 명령어


int a = 10;


decltype(a) b = 2; // int b = 2;


int& x = a;


decltype(x) c = b; // int& c = b;



const int i = 4;


auto j = i;  // int j = i;


decltype(i) k = i;  // const int k = i;




int arr1[10];


auto arr2 = arr1; // int* arr2 = arr1;


decltype(arr1) arr3 = arr1; // int arr3[10] 으로 선언








decltype 키워드


템플릿 함수에서 어떤 객체의 타입이 템플릿 인자들에 의해서 결정되는 경우



template <typename T, typename U>


void add(T t, U u, decltype(t + u)* result) {

   

    *result = t + u;


}


template <typename T, typename U>


auto add(T t, U u) -> decltype(t + u) {

  return t + u;

}







vector의 emplace_back( )과 push_back( )의 차이



push_back( ) 메서드


 - 일반적으로 '객체' 삽입


 - 객체가 없이 삽입하려면 임시 객체(rvalue) 가 있어야 함


 - 암시적 형 변환이 가능하다면 인자로도 삽입 


 - 이는 인자를 통해 임시객체를 암시적으로 생성한 후 삽입




std::vector<myString> vecString;


myString str = "hello1";


vecString.push_back(str); // str 객체 소멸


vecString.push_back(myString("hello2")); // 임시 객체 소멸


vecString.push_back("hello3"); // 임시 객체 소멸


vecString.push_back(std::move(myString("hello4")); // 해제 안 됨



대입에 관한 이동 연산자


myString& operator=(myString&& right);























2020. 11. 19. 15:36

인다이렉션

프로그래밍/C++ 2020. 11. 19. 15:36

인다이렉션의 정의


 - 어떤 기능을 수행하는 코드가 직접 들어 있는 것이 아니라 기능 별로 분리되어 있는 다른 메서드를 참조하는 방식


- 값 자체가 아니라 이름, 참조, 컨테이너 등을 사용해서 대상을 참조


- C 언어의 포인터, C++ 템플릿


인다이렉션의 장점


 - 로직의 공유 : 두 위치에서 호출되는 하위 메서드나 모든 하위 클래스가 공유하는 상위 클래스의 메서드 등


의도와 구현을 따로 나타냄 : 






리팩토링을 할 때의 문제


 - 데이터 베이스


 - 인터페이스 변경


 - 언제 리팩토링을 하지 말아야 하는가?

 

 마감일이 얼마 남지 않았을 때

 

 코드를 처음부터 다시 작성해야 할 때 





리팩토링과 디자인


리팩토링은 디자인을 보완


단순한 디자인을 변경하는 것은 비용이 너무 크다



100 가지 중에서 실제 문제가 발생하는 부분은 


찾아서 수정 필요






2020. 11. 19. 15:28

1. 삼진 규칙 (세 번째로 비슷한 것을 할 때)


2. 새로운 기능을 추가할 때


3. 버그를 수정할 때


4. 코드 리뷰를 할 때


5. 깊이 있는 이해라를 위한 리팩토링


 - 개발자로서 코드 기반을 더 깊이 이해하면, 보다 효과적으로 자신의 코드를 보충하거나 코드 개선 방법을 제시


품질을 고려하는 사람이면 리팩토링이 버그를 줄이고 개발 속도롤 빠르게 한다고 설득





2020. 11. 19. 15:24

리팩토링 (명사)


 - 겉으로 드러나는 기능은 그대로 둔 채 알아보기 쉽고 수정 간편하도록 소프트웨어 내보를 변경하는 작업



리팩토링하다 (동사)


 - 여러 리팩토링을 적용해서 겉으로 드러나는 기능은 그대로 둔 채 소프트웨어의 구조를 변경


호출하는 함수는 그대로 둠



왜 리팩토링을 하는가?


1. 소프트웨어의 설계를 개선


2. 소프트웨어를 좀 더 이해하기 쉽게 만든다


3. 버그를 간단히 발견할 수 있게 도와준다


4. 개발자의 프로그래밍 속도가 빨라진다



2020. 9. 18. 17:24

배열은 이미 리스트 초기화를 사용하고 있으며, C++11에서는 몇 가지가 추가되었다


먼저, 배열을 초기화할 때, = 부호를 사용하지 않아도 된다


double earnings[4] { 1.2e4, 1.6e4, 1.1e4, 1.7e4 }; // C++11에서 문제 없음



두 번째로, 중괄호를 공백하여 모든 배열을 0으로 초기화할 수 있다


unsigned int counts[10] = { }; // 모든 배열값을 0으로 초기화


float balances[1000] { };      // 모든 배열값을 0으로 초기화



세 번째로, 리스트 초기화시에 narrowing을 방지할 수 있다


long plifs[ ] = { 25, 92, 3.0 };     // 허용 안 됨


char slifs[4] = { 'h', 'i', 1122011, '\0' } // 허용 안 됨


char tlifs[4] = { 'h', 'i', 112, '\0' } // 허용



plifs[ ]는 부동 소수점형에서 정수형으로 변환되기 때문에, 초기화가 실패하게 된다


심지어 소수점 아래 값이 0이라고 하더라도 실패한다


slifs[4]는 

2020. 9. 18. 11:38

C++11은 초기화하는 값을 보고 변수형을 추론할 수 있다


초기화 선언 시 데이터형을 쓰지 않고 auto를 사용할 수 있다


auto n = 100;   // n은 int


auto x = 1.5;   // x는 double


auto y = 1.3e12L; // y는 long double


그러나 자동으로 데이터형을 추론하는 것을 그렇게 단순하게 생각해서는 안 된다


안 좋은 습관을 가질 수 있다


예를 들어 x, y, z가 모두 double 형이고 다음과 같은 코드를 작성하면


auto x = 0.0 ;   // 0.0이 double이기 때문에 문제가 없음


double y = 0;    // 0이 자동으로 0.0으로 변환되기 때문에 문제가 없음


auto z = 0;      // 이런! 0이 int이기 때문에, z가 int가 되어 문제가 생김


0.0 대신 0을 사용할 경우 문제가 발생하지는 않는다


그러나, 자동 형변환의 경우에는 문제가 발생한다


자동으로 변수형을 추론하는 것은 STL(Standard Template Library)을 사용할 때와

같이 복잡한 변수형을 다룰 때 매우 유용하다


예를 들어 C++98에서는 다음과 같이 코드가 작성된다


std::vector<double> scores;


std::vector<double>::iterator pv = scores.begin();


반면, 코드가 C++11에서는 다음과 같이 작성될 수 있다


std::vector<double> scores;


auto pv = scores.begin();


2020. 7. 27. 20:35

* 프레임의 구조


상위 수준에서 게임은 각 프레임마다 다음 단계를 수행한다


1. 입력을 받는다


2. 게임 세계를 갱신한다


3. 출력을 만든다


입력 처리는 마우스나 키보드, 또는 컨트롤러 같은 여러 디바이스의 입력을 감지한다


게임의 입력은 궁극적으로 게임의 유형이나 게임이 실행되는 플랫폼에 의존한다



게임 세계의 갱신은 게임 세계의 모든 오브젝트를 거치면서 필요에 따라 게임 오브젝트를 갱신한다는 걸 뜻한다

2019. 9. 18. 11:39


Console 에서 MFC를 사용할 때 다음 헤더 파일을 포함해야 한다


#include <afxext.h>


Console 에서 MFC 함수를 사용하면 다음과 같은 에러가 난다


fatal error C1189: #error:  Building MFC application with /MD[d] (CRT dll version) requires MFC shared dll version. Please #define _AFXDLL or do not use /MD[d]


원인은 다음과 같다


MFC 공유 DLL을 사용하기 위해서는 MD 대신 MT 로 변경한다


구성 속성 - C/C++ - 코드 생성 - 런타임 라이브러리 - 다중 스레드(/MT)


그리고 전처리기 CONSOLE 대신 WIN32 와  _WINDOWS를 추가한다


NDEBUG;WIN32;_WINDOWS;%(PreprocessorDefinitions)



2019. 3. 20. 00:15

Visual Studio 2015에서


도구 - 옵션 - 텍스트 편집기 - C/C++ - 서식 - 간격 - 제어 블록의 간격 

- 제어 흐름 문의 키워드와 여는 괄호 사이에 공백을 삽입합니다


항목을 체크 해제한다