김형준 GIS 연구소 (for Developers)  
Front Page
Notice | E-Mail | Admin | Write Article   
 
2007/11/28 16:11 2007/11/28 16:11
C++에서 기본클래스의 생성자에서는 순수가상함수를 호출할 수 없다!?
다소 황당하기도 하고, 언젠가 책에서 본것같기도 한 내용입니다. 하지만 저는 당연이 되리라 생각했던지라... 왜 않되냐며 약간 열 받기도 하였습니다. 어떤 내용인냐면...

먼저 Base라는 클래스가 있고, 이 클래스는 A라는 순수 가상 함수가 있습니다.
class Base {
public:
	Base() { };

	void TTT() {
		A();
	}

public:
	virtual void A() = 0;
};
보시면 TTT라는 함수에서 A 함수를 호출하고 있구요. 이제 Base를 상속받는 Derv라는 함수를 정의해 봅니다.
class Derv : public Base {
public:
	virtual void A() {
		printf("impl");
	}
};
상속받는 클래스는 기본 클래스의 순수 가상 함수를 구현해야할 책임이 있으므로 A 함수를 구현합니다. 이제 Base 함수를 사용해 보면...
int _tmain(int argc, _TCHAR* argv[])
{
	Base *p = new Derv();

	p->TTT();

	delete p;

	return 0;
}
화면상에 "impl"이라는 문자가 찍힙니다. 잘됩니다. 그렇다면 Base 클래스를 아래처럼 수정합니다.
class Base {
public:
	Base() { A(); };

	void TTT() {
		A();
	}

public:
	virtual void A() = 0;
};
변경된 부분은 Base의 생성자에서 순사 가상 함수를 호출하고 있습니다. 실행해보면... 않됩니다. Base::A(void) 외부 기호를 확인할 수 없다는 경고입니다. 원래 C++ 표준도 않되는 것인지.. 아니면 MS의 C++ 만 않되는 것인지는 모르겠지만, 당연히 될줄알고 사용했던지라 매우 난감했습니다. 아무튼 않되는 것을 알았으니 돌아가야겠습니다.

Track this back : http://www.gisdeveloper.co.kr/trackback/346
Commented by ParkPD at 2007/11/29 00:58  r x
다른 책에서도 언급되는 걸로 보아 다른 C++ 컴파일러에서도 마찬가지일 듯 합니다.(그러나 저도 MSVC 만 써 봤군요)
OnCreate 같은 템플릿 메서드가 나오게 된 이유 중 하나는 이런 문제가 아닐까 하는 생각도 드네요.
Commented by 김형준 at 2007/11/29 02:10  r x
ParkPD님, 멋진 블로그를 운영하시는군요. 블로그에 접속하니.. 웅장한 음악이 나오길레 제 블로그에도 배경음악 넣어도 괜찬을듯하다.. 했습니다. 알고보니 게시글중 리니지 동영상에서 흘러나오는.. ^^;
Commented by 지호 at 2007/11/29 11:57  r x
생성자 호출이 완료 될 때까지 객체는 완성된 것이 아니라는 관점에서 본다면 오히려 가상함수를 (순수든 아니든간에) 호출하는게 잘못되었다고 볼 수 있습니다. 가상함수란건 각 타입에 맞는 함수를 호출한다는 의미니까요.

구현상 가상함수 테이블을 구성하는 코드가 생성자에 숨어있는데 그 구성 전에 가상함수를 호출하게 되니 문제가 생기겠죠.

생성자에서는 절대 가상함수를 사용해선 안됩니다.
이게 말은 쉬운데 호출하는 함수가 가상이 아니더라도 그 함수가 다시 가상함수를 호출하는 경우도 마찬가지로 문제가 생깁니다.
effective c++에 관련 항목이 있으니 읽어보시면 이해가 더 빠르실 겁니다.
Commented by 김형준 at 2007/11/29 13:21  r x
지호님의 말씀 중에, "구현상 가상함수 테이블을 구성하는 코드가 생성자에 숨어있다"라는 것에, 왜 생성자에서는 가상함수 호출이 않되는지의 이유가 명확하게 들어나있군요.. 그런데, 생성자에서 가상함수를 호출해줘야할 필요성이 분명 있습니다. ParkPD님께서 말씀하신 OnCreate 같은 템플릿이 필요한 이유도 이때문이구요. 생성자에서 가상함수를 호출할 수 있다면 OnCreate 같은 템플릿도 필요없을텐데... 하지만 역시 지호님의 말씀처럼 가상함수테이블의 생성이 생성자에서 이루어진다라는 C++ 스펙대로라면, 생성자에서 가상함수 호출은 OnCreate 같은 템플릿을 이용하는 방법으로 가야겠습니다.


name    password    homepage
 hidden
BLOG main image
 Notice
DuraMap-Xr 소개 및 다운로드
[오픈소스] SimpleSHP v0.1
FingerEyes-Xr 소개 및 다운로드
OpenGL Tutorials
 Category
전체 (531)
GIS 개발 (146)
프로그래밍 (233)
스치는 생각들 (129)
번역 또는 집필 (3)
 TAGS
GIS Xr OpenGL Shader FingerEyes BlackPoint Algorithm Java Map Engine WPF
 Calendar
«   2012/02   »
      1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29      
 Recent Entries
[FingerEyes] 지오메트리...
[FingerEyes] Geometry로...
[FingerEyes] FID 리스트...
[FingerEyes] UPDATE, INS...
영화, "부러진 화살"
 Recent Comments
메일로 답변드렸습니다....
김형준 - 02/01
txt파일을 엑셀로 변환하...
최상준 - 02/01
코봉히님두 새해 복 많이...
김형준 - 01/25
아 너무 감사합니다. 새해...
코봉히 - 01/23
wkb는 http://www.gisdeve...
김형준(Dip2K) - 01/23
wkb의 구조가 shp파일의...
코봉히 - 01/20
wkb는 바이너리인지라.....
김형준(Dip2K) - 01/20
정말 좋은 정보 감사합니...
코봉히 - 01/20
은빛소나기님의 블로그를...
김형준 - 01/20
네, 빨간색으로 표시되는...
김형준 - 01/20
 Archive
2012/02
2012/01
2011/12
2011/11
2011/10
2011/09
2011/08
2011/07
2011/06
2011/05
2011/04
2011/03
 Link Site
Adobe Flex 3 Help
Cartograph 2.0
GADM
GIS 위키디피아
GIS 프로그래밍 연구소
MapTools.org
OGC
OGRE3D
OSGeo 한국 지부
Paul Bourke Site
Wikipedia
국가수자원관리 정보시스템
국립지리원
국토연구원
국토해양부
네이버 과학
대한측량협회
류광님의 블로그
이민파님의 공간분석과 리...
지오서비스(GeoService)
 Visitor Statistics
Total : 928714
Today : 193
Yesterday : 317
태터툴즈 배너
rss