CObject

유혜정·2022년 4월 12일
0
post-thumbnail

객체 생성 방법

  1. A obj;
    A obj(); // 안됨! 함수선언으로 인식! 함수명: obj / return type: A
    A obj{}; // 요즘 추천하는 방식
  2. A pObj = new A();
    A
    pObj = new A;
    A* pObj = new A{}; // 요즘 추천하는 방식

RTTI -> RunTime Type Information

CObject

CObject () : 최고 기반 클래스

class A : public CObject {
public:
	A() {
		TRACE("A() 생성자 호출\n");
	}
	~A() {
		TRACE("~A() 소멸자 호출\n");
	}
};

class B : public CObject {
public:
	B() {
		TRACE("B() 생성자 호출\n");
	}
	~B() {
		TRACE("~B() 소멸자 호출\n");
	}
};
class CMYApp : public CWinApp {
public:
	BOOL InitInstance() {
		CMainFrame* pMainFrame = new CMainFrame();
		// pMainFrame->Create(NULL, NULL);
		pMainFrame->LoadFrame(IDR_MAIN_FRAME);

		pMainFrame->ShowWindow(SW_SHOW);
		m_pMainWnd = pMainFrame;

		// CObject* pObj = NULL; // C style
		// NULL : int type
		CObject* pObj = nullptr; // C++ style
		// nullptr : void type
		pObj = new A; // 특별화 : A라고 고정되어 있기 때문
		delete pObj;

		pObj = new B;
		delete pObj;

		/*
		객체 생성 방법
		1. A obj;
			A obj(); // 안됨! 함수선언으로 인식! 함수명: obj / return type: A
			A obj{}; // 요즘 추천하는 방식
		2. A* pObj = new A();
			A* pObj = new A;
			A* pObj = new A{}; // 요즘 추천하는 방식

		RTTI -> RunTime Type Information

		CObject () : 최고 기반 클래스

		*/

		return TRUE;
	}
	int ExitInstance() {
		return 0;
	}
};

CMYApp theApp;

디버깅으로 진행한 출력 결과

// 정상적인 호출
		pObj = new A; // 특별화 : A라고 고정되어 있기 때문
		((A*)pObj)->add(10, 20);
		delete pObj;

		pObj = new B;
		((B*)pObj)->sub(10, 20);
		delete pObj;

//비정상적인 호출
		pObj = new A; // 특별화 : A라고 고정되어 있기 때문
		((B*)pObj)->sub(10, 20);
		delete pObj;

		pObj = new B;
		((A*)pObj)->add(10, 20);
		delete pObj;

// 컴파일 오류
class A : public CObject {
private:
	int a;
	int b;
public:
	A() : a(100), b(100) {
		TRACE("A() 생성자 호출\n");
	}
	~A() {
		TRACE("~A() 소멸자 호출\n");
	}

	int add(int a, int b) {
		TRACE("A::add() 호출 = %d\n" + (this->a + this->b + a + b));
		return this->a + this->b + a + b;
	}
};

class B : public CObject {
private:
	int b;
public:
	B() : b(200) {
		TRACE("B() 생성자 호출\n");
	}
	~B() {
		TRACE("B() 소멸자 호출\n");
	}
	int add(int a, int b) {
		return a + b;
	}
	int sub(int a, int b) {
		TRACE("B::sub() 호출 = %d\n" + (this->b + (a - b)));
		return this->b + (a - b);
	}
};

DECLARE_DYNAMIC 사용

형변환 함수로 오류 탐지

// 형변환 확인 함수
		pObj = new A; // 특별화 : A라고 고정되어 있기 때문
		if(pObj->IsKindOf(RUNTIME_CLASS(A)))
			((A*)pObj)->add(10, 20);
		else if(pObj->IsKindOf(RUNTIME_CLASS(A)))
			((B*)pObj)->sub(10, 20);

제대로된 데이터 확인 방법

class A : public CObject {
	DECLARE_DYNAMIC(A); // 정확한 데이터를 위해서 입력해야 함
private:
	int a;
	int b;
public:
	A() : a(100), b(100) {
		TRACE("A() 생성자 호출\n");
	}
	~A() {
		TRACE("~A() 소멸자 호출\n");
	}

	int add(int a, int b) {
		TRACE("A::add() 호출 = %d\n", (this->a + this->b + a + b));
		return this->a + this->b + a + b;
	}
};

class B : public CObject {
	DECLARE_DYNAMIC(B);
private:
	int b;
public:
	B() : b(200) {
		TRACE("B() 생성자 호출\n");
	}
	~B() {
		TRACE("B() 소멸자 호출\n");
	}
	int add(int a, int b) {
		return a + b;
	}
	int sub(int a, int b) {
		TRACE("B::sub() 호출 = %d\n", (this->b + (a - b)));
		return this->b + (a - b);
	}
};

IMPLEMENT_DYNAMIC(A, CObject); // 정확한 데이터를 위해서 입력해야 함
IMPLEMENT_DYNAMIC(B, CObject);

DECLARE_DYNCREATE 사용

class A : public CObject {
	// DECLARE_DYNAMIC(A); // 정확한 데이터를 위해서 입력해야 함
	// DECLARE_DYNAMIC : CObject::IsKindOf()을 위한 선언
	
	DECLARE_DYNCREATE(A) // CObject::IsKindOf(), 객체 생성의 일반화를 제공 : CRuntimeClar=============못적음

private:
	int a;
	int b;
public:
	A() : a(100), b(100) {
		TRACE("A() 생성자 호출\n");
	}
	~A() {
		TRACE("~A() 소멸자 호출\n");
	}

	int add(int a, int b) {
		TRACE("A::add() 호출 = %d\n", (this->a + this->b + a + b));
		return this->a + this->b + a + b;
	}
};

class B : public CObject {
	DECLARE_DYNAMIC(B);
private:
	int b;
public:
	B() : b(200) {
		TRACE("B() 생성자 호출\n");
	}
	~B() {
		TRACE("B() 소멸자 호출\n");
	}
	int add(int a, int b) {
		return a + b;
	}
	int sub(int a, int b) {
		TRACE("B::sub() 호출 = %d\n", (this->b + (a - b)));
		return this->b + (a - b);
	}
};

// IMPLEMENT_DYNAMIC(A, CObject); // 정확한 데이터를 위해서 입력해야 함
// IMPLEMENT_DYNAMIC(B, CObject);
// IMPLEMENT_DYNAMIC : 부모 자식 관계의 연결고리를 만들어 주는 것

IMPLEMENT_DYNCREATE(A, CObject);
// 부모 자식 관계의 연결고리를 만들어 주는 것 ==================== 못들음

factory

// 객체를 생성하는 디자인 패턴
// factory design pattern

class A : public CObject {

private:
	int a;
	int b;
public:
	A() : a(100), b(100) {
		TRACE("A() 생성자 호출\n");
	}
	~A() {
		TRACE("~A() 소멸자 호출\n");
	}

	int add(int a, int b) {
		TRACE("A::add() 호출 = %d\n", (this->a + this->b + a + b));
		return this->a + this->b + a + b;
	}
	// static 클래스를 통해서 제작 가능: factory
	static A* CreateObject() {
		return new A;
	}
};

static A* CreateObject() 방식이 아닌, MFC방식으로 구현

		CObject* pObj = nullptr;
		// pObj = new A; // 특별화
		CRuntimeClass* pClass = RUNTIME_CLASS(A);
		// MFC에서 factory 형식으로 class 객체 생성
		pObj = pClass->CreateObject(); // 일반화

		pClass = RUNTIME_CLASS(B);
		pObj = pClass->CreateObject(); // 일반화

그 외에 여러 함수들

IMPLEMENT (구현) : 의미를 부여한 메크로
IMPLEMENT_DYNCREATE를 하게 되면

A::CreateObject() {
return new A;
}
가 추가적으로 생생된 것임


	// DECLARE_DYNAMIC(A); // 정확한 데이터를 위해서 입력해야 함
	// DECLARE_DYNAMIC : CObject::IsKindOf()을 위한 선언
	
	//DECLARE_DYNCREATE(A); // CObject::IsKindOf(), 객체 생성의 일반화를 제공 : CRuntimeClass::CreateObject()
	
	DECLARE_SERIAL(A); // CObject::IsKindOf(), 객체 생성의 일반화를 제공 : CRuntimeClass::CreateObject(), CObject::Serialize()
	// CObject::Serialize() : '저장소에 저장하고, 읽기 기능 제공' 호출 가능

// IMPLEMENT_DYNAMIC(A, CObject); // 정확한 데이터를 위해서 입력해야 함
// IMPLEMENT_DYNAMIC(B, CObject);
// IMPLEMENT_DYNAMIC : 부모 자식 관계의 연결고리 만들기

// IMPLEMENT_DYNCREATE(A, CObject);
// 부모 자식 관계의 연결고리 만들기, 개게 생성의 일반화에 대한 함수 제공

IMPLEMENT_SERIAL(A, CObject, 1)
// 부모 자식 관계의 연결고리 만들기, 개게 생성의 일반화에 대한 함수 제공, 읽기 쓰기에 대한 기능을 제공 및 사용 가능

전체코드

#include <afxwin.h>
#include "resource.h"
// 객체를 생성하는 디자인 패턴
// factory design pattern

class A : public CObject {
	// DECLARE_DYNAMIC(A); // 정확한 데이터를 위해서 입력해야 함
	// DECLARE_DYNAMIC : CObject::IsKindOf()을 위한 선언
	
	//DECLARE_DYNCREATE(A); // CObject::IsKindOf(), 객체 생성의 일반화를 제공 : CRuntimeClass::CreateObject()
	
	DECLARE_SERIAL(A); // CObject::IsKindOf(), 객체 생성의 일반화를 제공 : CRuntimeClass::CreateObject(), CObject::Serialize()
	// CObject::Serialize() : '저장소에 저장하고, 읽기 기능 제공' 호출 가능

private:
	int a;
	int b;
public:
	A() : a(100), b(100) {
		TRACE("A() 생성자 호출\n");
	}
	~A() {
		TRACE("~A() 소멸자 호출\n");
	}

	int add(int a, int b) {
		TRACE("A::add() 호출 = %d\n", (this->a + this->b + a + b));
		return this->a + this->b + a + b;
	}
	//// static 클래스를 통해서 제작 가능: factory
	//static A* CreateObject() {
	//	return new A;
	//}
};

class B : public CObject {
	DECLARE_DYNAMIC(B);
private:
	int b;
public:
	B() : b(200) {
		TRACE("B() 생성자 호출\n");
	}
	~B() {
		TRACE("B() 소멸자 호출\n");
	}
	int add(int a, int b) {
		return a + b;
	}
	int sub(int a, int b) {
		TRACE("B::sub() 호출 = %d\n", (this->b + (a - b)));
		return this->b + (a - b);
	}
};

/*
IMPLEMENT (구현) : 의미를 부여한 메크로
IMPLEMENT_DYNCREATE를 하게 되면 

A::CreateObject() {
	return new A;
}
가 추가적으로 생생된 것임
*/

// IMPLEMENT_DYNAMIC(A, CObject); // 정확한 데이터를 위해서 입력해야 함
// IMPLEMENT_DYNAMIC(B, CObject);
// IMPLEMENT_DYNAMIC : 부모 자식 관계의 연결고리 만들기

// IMPLEMENT_DYNCREATE(A, CObject);
// 부모 자식 관계의 연결고리 만들기, 개게 생성의 일반화에 대한 함수 제공

IMPLEMENT_SERIAL(A, CObject, 1)
// 부모 자식 관계의 연결고리 만들기, 개게 생성의 일반화에 대한 함수 제공, 읽기 쓰기에 대한 기능을 제공 및 사용 가능

class CMainFrame : public CFrameWnd {

};

class CMYApp : public CWinApp {
public:
	BOOL InitInstance() {
		CMainFrame* pMainFrame = new CMainFrame();
		// pMainFrame->Create(NULL, NULL);
		pMainFrame->LoadFrame(IDR_MAIN_FRAME);

		pMainFrame->ShowWindow(SW_SHOW);
		m_pMainWnd = pMainFrame;


		CObject* pObj = nullptr;
		// pObj = new A; // 특별화
		CRuntimeClass* pClass = RUNTIME_CLASS(A);
		// MFC에서 factory 형식으로 class 객체 생성
		pObj = pClass->CreateObject(); // 일반화

		pClass = RUNTIME_CLASS(B);
		pObj = pClass->CreateObject(); // 일반화




		// CObject* pObj = NULL; // C style
		// NULL : int type
		CObject* pObj = nullptr; // C++ style
		// nullptr : void type
		pObj = new A; // 특별화 : A라고 고정되어 있기 때문
		if (pObj->IsKindOf(RUNTIME_CLASS(A))) { // IsKindOf : object type 판별
			((A*)pObj)->add(10, 20);
		}
		else if (pObj->IsKindOf(RUNTIME_CLASS(B))) {
			((B*)pObj)->sub(10, 20);
		}
		else {
			TRACE("abababababab\n");
		}

		delete pObj;

		pObj = new B;
		if (pObj->IsKindOf(RUNTIME_CLASS(A))) {
			((A*)pObj)->add(10, 20);
		}
		else if (pObj->IsKindOf(RUNTIME_CLASS(B))) {
			((B*)pObj)->sub(10, 20);
		}
		else {
			TRACE("abababababab\n");
		}
		delete pObj;

		/*
		객체 생성 방법
		1. A obj;
			A obj(); // 안됨! 함수선언으로 인식! 함수명: obj / return type: A
			A obj{}; // 요즘 추천하는 방식
		2. A* pObj = new A();
			A* pObj = new A;
			A* pObj = new A{}; // 요즘 추천하는 방식

		RTTI -> RunTime Type Information

		CObject () : 최고 기반 클래스

		*/

		return TRUE;
	}
	int ExitInstance() {
		return 0;
	}
};

CMYApp theApp;
profile
내가 시작한 공부, 공유할 코드

0개의 댓글