C++ .h만 인클루드했는데 왜 .cpp도 링크에 포함되나요?

shori0917의 이미지

웹개발자인데요. 일본소셜게임회사에 전직하게되었습니다.

집에서 독학으로 Cocos2d-x를 공부하는데요

도무지 혼자서 해결이 안돼서 질문해봅니다.

통합환경툴이 자동으로 링크? 인클루드? 해준다는데 이해가 잘 안가네요?

cocos2d-x예제는 sample에 있는데 hellocpp예제의 일부입니다.

// AppDeligate.cpp
#include "HelloWorldScene.h"

bool AppDelegate::applicationDidFinishLaunching() {
Scene *scene = HelloWorld::scene();
}

// HelloWorldScene.cpp
#include "HelloWorldScene.h"
#include "AppMacros.h"
USING_NS_CC;

Scene* HelloWorld::scene()
{
// 'scene' is an autorelease object
Scene *scene = Scene::create();

// 'layer' is an autorelease object
HelloWorld *layer = HelloWorld::create();

// add layer as a child to scene
scene->addChild(layer);

// return the scene
return scene;
}

// HelloWorldScene.h
#ifndef __HELLOWORLD_SCENE_H__
#define __HELLOWORLD_SCENE_H__

#include "cocos2d.h"

class HelloWorld : public cocos2d::Layer
{
public:
// Here's a difference. Method 'init' in cocos2d-x returns bool, instead of returning 'id' in cocos2d-iphone
virtual bool init();

// there's no 'id' in cpp, so we recommend returning the class instance pointer
static cocos2d::Scene* scene();

// a selector callback
void menuCloseCallback(Object* sender);

// implement the "static node()" method manually
CREATE_FUNC(HelloWorld);
};

#endif // __HELLOWORLD_SCENE_H__

어째서 AppDeligate.cpp에서 "Scene *scene = HelloWorld::scene();"를 할수 있는거지요?
단지 "HelloWorldScene.h"만 인클루드 했을뿐인데 HelloWorldScene.cpp에 있는 정의 부분을 알고 있다는게 이상하네요??
참고로 이클립스 쓰고 있고요. HelloWorld::scene(); 에서 F3누르면 HelloWorldScene.cpp로 점프합니다.

ifree의 이미지

.h 파일에 넘겨지는 인수와 리턴 타입이 명시되어 있기 때문에, 이 정보만 가지고 함수 호출 코드를 포함하는 오브젝트 파일들을 구성할 수 있습니다.
이 오브젝트 파일들을 모아서 실행파일을 만드는 링크 과정에서 실제 함수의 주소가 포함되게 되죠.

peecky의 이미지

컴파일은 cpp 파일 단위로 합니다. 그러면 AppDeligate.cpp를 컴파일한 AppDeligate.o 파일이 생성되고, HelloWorldScene.cpp 파일을 컴파일한 HelloWorldScene.o 파일이 생성됩니다. (컴파일러에 따라서 확장자가 .o가 아닐 수도 있습니다)
컴파일 과정에서는 함수의 선언 부분(함수 호출에 대한 규격)만 있어도 컴파일이 가능합니다. (그리고 이 선언 부분을 재작성하는 것을 피하기 위해 헤더 파일(.h)로 분리하고 include 합니다)

링크는 컴파일한 오브젝트 파일(.o 파일들)을 합쳐서 하나의 실행파일로 만드는 과정입니다. 만약 링크 과정에서 모든 .o 파일을 둘러봐도 HelloWorld::scene() 함수의 정의 부분이 없으면 링크 에러가 납니다. (또한 정의가 두 개 이상 발견돼도 에러가 납니다)

링크 과정이 끝나면 그제서야 실행이 가능합니다.

질문으로 돌아가서, AppDeligate.cpp에서 HelloWorld::scene()을 호출할 수 있는 이유는, App.Deligate.cpp 에서 함수의 호출 규격을 알고 있고, 링크 과정을 거친 실행파일에 HelloWorld::scene() 함수의 정의가 포함되어 있기 때문입니다.

dltkddyd의 이미지

질문의 요지가

main.cc
#include "file.h"

하고 main.cc 를 컴파일 할 때 file.cc 파일이 어떻게 링크가 걸리느냐는 것으로 이해하고 답변을 드립니다.
포괄적으로 컴파일이라고 하는 것은 목적코드인 .obj를 만드는 과정과 .cc 파일들을 걸어주는 링크 과정으로 나뉩니다. 좁게는 컴파일을 목적코드를 만드는 과정으로 설명하기도 합니다. 좁게 말하자면 프로그램의 번역과정은 컴파일과정과 링크과정입니다.

그런데 넓은 의미의 컴파일을 하기 위해서 다음과 같이 명시합니다.

g++ -o main main.cc file.cc

그러면 컴파일러는 file.cc가 링크가 걸릴 파일이라는 정보를 받고 링크 시에 저 파일을 연결해서 기계어 코드를 만듭니다. 정보가 없다면 기계도 적절한 처리를 할 수 없겠죠. 당연한 말이지만요....

본인 맞습니다.
인증샷
우헤헤헤... 로 대신합니다.

shori0917의 이미지

마지막에 결국에는 실행파일을 만들때 정보를 가지게되는군요.
답변 감사합니다.

shint의 이미지


클래스에서 static으로 변수를 지정하면. 전역적으로 사용할 수 있게 됩니다.
자세한것은 책'을 참고해 봐야할거 같습니다. ㅇ_ㅇ;;

//네임스페이스와 상속. 그리고. 다형성. 사용방법 연습
 
namespace A1
{
	class C1
	{
	public:
		C1(){};
		~C1(){};
		void fn(){	printf("test1\n");	};
	};
}
 
namespace B1
{
	class C2 : public A1::C1
	{
	public:
		C2(){};
		~C2(){};
		static void fn_static()		{	printf("fn_static()\n");	};
		void fn_no_static()			{	printf("fn_no_static()\n");	};
		void fn()					{	printf("test2\n");	};
//		virtual void fn()			{	printf("test2\n");	};
//		static void B1::C2::fn()	{	printf("test2\n");	};
//		static void A1::C1::fn()	{	printf("test2\n");	};
	};
}
 
 
 
 
// 유일한 응용 프로그램 개체입니다.
 
CWinApp theApp;
 
using namespace std;
 
int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
{
	int nRetCode = 0;
 
	A1::C1 a;
	B1::C2 b;
 
	a.fn();
	b.fn();
 
	A1::C1* c;
	c = (A1::C1*)&b;
	c->fn();
 
	B1::C2* d;
	d = (B1::C2*)&a;
	d->fn();
 
	//namespace::클래스::변수나 함수 이름으로 접근
	//파일이 다를경우. using namespace 이름; 으로 접근할 수 있거 같습니다. ㅡ_ㅡ;; 안해봄.
	B1::C2::fn_static();		//static 전역변수처럼 사용하면 됩니다.
//	B1::C2::fn_no_static();		//빌드 안됨. 비정적 멤버 함수를 잘못 호출했습니다.
 
	system("pause");
	return nRetCode;
}

----------------------------------------------------------------------------
젊음'은 모든것을 가능하게 만든다.

매일 1억명이 사용하는 프로그램을 함께 만들어보고 싶습니다.
정규 근로 시간을 지키는. 야근 없는 회사와 거래합니다.

각 분야별. 좋은 책'이나 사이트' 블로그' 링크 소개 받습니다. shintx@naver.com

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • You can use Textile markup to format text.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.