3 장더나은 C 로서의 C++ (2) 인라인함수참조 (reference) 의이해함수에대한참조참조와함수참조의반환 linkage 지정선언과정의객체지향프로그래밍 C++ 프로그래밍입문
1. 인라인함수 예 : x, y 값중최소값을반환하는매크로와함수작성 // 매크로로구현한경우 #define MIN(X, Y) ((X) < (Y)? (X) : (Y)) X, Y 각각을괄호 ( ) 안에넣는이유는? // 함수로구현한경우 cout << MIN(4, 5) << endl; int MIN(int X, int Y) cout << MIN((2 + 3), (1 + 2)) << endl; return (X < Y? X : Y); main 함수는동일! cout << MIN(4, 5) << endl; cout << MIN((2 + 3), (1 + 2)) << endl; 3 장더나은 C 로서의 C++ (2) 1
1. 인라인함수 매크로 전처리단계에서해당문장으로대치 à 전처리기담당 장점 : 실행시수행속도빨라짐 단점 내용이많은경우실행파일의크기가커짐 à 내용이짧은경우사용 코드의가독성 (readability) 이떨어짐 함수 컴파일시해당함수의주소만기록, 실행시해당주소로이동 단점 : 상대적으로수행속도가느려짐 함수의모양을하면서도매크로처럼동작하게하는방법 인라인함수 (inline function) 작성은함수처럼, 동작은매크로처럼 à 수행속도가빨라짐 인라인함수로만드는방법 : 함수정의시 inline 키워드추가 ü inline int MIN(int X, int Y) return X < Y? X : Y; 3 장더나은 C 로서의 C++ (2) 2
1. 인라인함수 다음중제대로동작하는것은? ß 인라인함수의장점 #define MULTI(X, Y) (X * Y) inline int MULTI(int X, int Y) return (X * Y); MULTI(1 + 2, 3 + 4) 를수행하는경우! 예 : Factorial 을계산하는 Fact 함수를인라인함수로. inline int Fact(int n) // 재귀호출함수 return ((n <= 1)? 1 : n * Fact(n-1)); cout << "5! = " << Fact(5) << endl; inline 선언은인라인함수로동작하도록요청하는것 à 실제인라인함수로의동작 ( 대치 ) 여부는컴파일러에의해결정됨 똑똑한컴파일러 : 120 으로대치덜똑똑한컴파일러 : 5 * Fact(4) 로대치멍청한컴파일러 : 인라인함수포기 3 장더나은 C 로서의 C++ (2) 3
2. 참조의이해 참조변수 기존변수의또다른이름. 홀로존재할수없음. 선언과동시에어떤변수에대한다른이름인지초기화필수 방법 : & int Var = 2; int &refvar = Var; // refvar 와 Var 는동일한변수 예 : 다음프로그램의출력결과분석 ref 와 var1 은동일한변수 int var1 = 3; int var2 = 5; int &ref = var1; ref = 7; cout << "var1 : " << var1 << ", var2 : " << var2 << ", ref : " << ref << endl; ref 에값 5 대입! ref = var2; cout << "var1 : " << var1 << ", var2 : " << var2 << ", ref : " << ref << endl; 3 장더나은 C 로서의 C++ (2) 4
2. 참조의이해 주의사항 : 값이나수식에대한참조불가능 int &ref = a + b; // X int &ref = 4; // X 예 : 출력결과는무엇인가? int var = 2; int &ref1 = var; int &ref2 = ref1; ref1 = 5; cout << "var : " << var << endl; cout << "ref1 : " << ref1 << endl; cout << "ref2 : " << ref2 << endl; 3 장더나은 C 로서의 C++ (2) 5
3. 함수에대한참조 예 : 함수포인터만들기 int sum(int x, int y) return (x + y); int (*psum)(int, int); psum = sum; // 함수포인터 // sum 함수를가리킴 cout << psum(3, 4) << endl; sum 함수와동일하게사용가능 함수에대한참조 int (&rsum)(int, int) = sum; // 기존함수에대한참조 rsum(3, 4); // sum 함수와동일하게사용가능 3 장더나은 C 로서의 C++ (2) 6
3. 함수에대한참조 예 : 참조변수 ( 함수참조포함 ) 의다양한사용예 int sum(int x, int y) return (x + y); int main() int a; int &b = a; int *p = &b; int &c = b; c = 5; cout << "a : " << a << endl; cout << "b : " << b << endl; cout << "*p : " << *p << endl; cout << "c : " << c << endl; // 여기서 & 는주소연산자임. 결국 a의주소가대입됨 // a, b, c는동일한변수 // a = 5; 와동일 int (&rsum)(int, int) = sum; cout << rsum(c, 5) << endl; // 함수에대한참조 int ary[3] = 0 ; int (&rary)[3] = ary; // 배열에대한참조 rary[2] = c; cout << ary[0] << " " << ary[1] << " " << ary[2] << endl; 3 장더나은 C 로서의 C++ (2) 7
4. 참조와함수 예 : 포인터를이용한 swap 함수작성 void swap(int *x, int *y) int temp = *x; *x = *y; *y = temp; int a = 3, b = 4; swap(&a, &b); // 참조에의한전달 // 주소전달 cout << "a = " << a << endl; cout << "b = " << b << endl; 참조를사용하여 swap 함수를재작성한다면?! 3 장더나은 C 로서의 C++ (2) 8
4. 참조와함수 참조를이용한 swap 함수 à 진정한참조에의한전달 void swap(int &x, int &y) int temp = x; x = y; y = temp; int a = 3, b = 4; swap(a, b); // 진정한참조에의한전달 // 변수자체전달 cout << "a = " << a << endl; cout << "b = " << b << endl; 형식매개변수로참조변수를사용하는경우 장점 : 속도향상 장점이자단점 : 형식매개변수변경시실매개변수까지변경됨 void sum(const int &x, const int &y); // x, y 값변경시에러발생 3 장더나은 C 로서의 C++ (2) 9
5. 참조의반환 변수값반환원리 int sum(int x, int y) int z = x + y; return z; int a = 3, b = 4; int result = sum(a, b); cout << result << endl; 1 z에대한임시변수생성 2 지역변수 z 메모리해제 3 임시변수전달 4 임시변수대입후임시변수메모리해제 3 장더나은 C 로서의 C++ (2) 10
5. 참조의반환 참조의반환이가능한가? 이것은무엇을의미하는가? 다음예는변수값의반환임! 참조의반환이아님! int sum(int x, int y) int z = x + y; int &refz = z; return refz; // refz와 z는동일한변수 // return z; 와동일, z값반환 다음예가바로참조의반환임! int &sum(int x, int y) int z = x + y; return z; // 참조의반환 // z 변수자체반환 이경우 z 변수자체를반환함그러나지역변수는사라지게되므로유효하지않은예. à 참조를반환하는유효한예는? à 어디에쓰는가? 3 장더나은 C 로서의 C++ (2) 11
5. 참조의반환 참조를반환하는유효한예 전역변수의 참조반환 int z; int &sum(int x, int y) z = x + y; return z; 참조로전달된변수의참조반환 // 참조의반환 // z 변수자체반환 int &min(int &x, int &y) // 매개변수참조전달및참조반환 return ((x < y)? x : y); int a = 3, b = 4; min(a, b) = 5; cout << "a = " << a << endl; cout << "b = " << b << endl; 함수호출이대입문의왼쪽에올수있는가? à 참조 ( 변수그자체 ) 를반환하기때문에가능! à 결국 a = 5; 와동일 3 장더나은 C 로서의 C++ (2) 12
5. 참조의반환 참조의반환은어디에쓰는가? 7장연산자오버로딩참조반환의사용예 int &GetArray(int *ary, int index) return ary[index]; // 참조반환 // index 에해당하는변수자체반환 int i; int ary[5]; for (i = 0; i < 5; i++) GetArray(ary, i) = i; // ary[i] = i; 와동일 for (i = 0; i < 5; i++) cout << "ary[" << i << "] " << GetArray(ary, i) << endl; 3 장더나은 C 로서의 C++ (2) 13
5. 참조의반환 다음프로그램의문제점은무엇인가? int &GetVar(void) int var = 5; return var; int &value = GetVar(); value = 3; // 지역변수 var 자체반환 실행은될수도있으나지역변수의참조반환은올바른사용이아님 cout << value << endl; 3 장더나은 C 로서의 C++ (2) 14
6. linkage 지정 C 와 C++ 의함수호출문에대한컴파일결과 à linkage C : 함수이름만저장 ß 함수오버로딩을허용하지않으므로구별가능 C++ : 함수이름 + 매개변수정보저장 ß 함수오버로딩허용 à mangled name C++ 에서 C 라이브러리의함수를호출하는경우 C : int func(int a); à func라는이름으로연결가능 C++ : func(3); à func+ 매개변수정보로 linkage 작성 함수호출과함수사이의 mismatch 발생 à 호출불가! C++ 컴파일시함수호출문을 C 형식으로컴파일하기 linkage 지정 : extern C 사용 extern C int func(int a); à 함수명 (func) 만으로 linkage 작성 3 장더나은 C 로서의 C++ (2) 15
6. linkage 지정 linkage 지정방법 extern "C" int func(int a); extern "C" int func(int a); 기존라이브러리에지정 extern "C" #include "clib.h" C++ 에서는어떻게 C 라이브러리의사용이가능할까? 예 : #include <stdio.h> stdio.h 파일내에는이미 extern C 선언이되어있음 필요에따라 C++ 형식의 컴파일시에는자동으로붙게됨 한꺼번에지정 int myfunc(void); void mysort(int *ary, int count); stdio.h #ifdef cplusplus extern "C" #endif... #ifdef cplusplus #endif C++ 컴파일시 _cplusplus 가자동정의됨 3 장더나은 C 로서의 C++ (2) 16
6. linkage 지정 다음프로그램에서어느한함수에만 extern C 를지정하는경우와 두함수모두 extern C 를지정하는경우에대해컴파일해보라. int sum(int x, int y) return (x + y); double sum(double x, double y) return (x + y); cout << sum(1, 2) << endl; cout << sum(1.1, 2.2) << endl; 3 장더나은 C 로서의 C++ (2) 17
7. 선언과정의 선언 (declaration) 식별자의타입정보를컴파일러에게알림 컴파일이되기위해서는식별자사용이전에선언이되어야함 선언의예 int a; extern int count = 1; // extern이라도값이대입된다면선언 & 정의가됨 int func(int x) return (x * x); // 함수의몸체가오는경우선언 & 정의 struct Point int x; int y; ; struct XCount int x; 이경우를제외하고모두선언인동시에정의! static int count; // static 멤버변수는선언일뿐정의는아님 ; int XCount::count = 1; // static 멤버변수는명시적으로외부에정의해야됨 // 초기화는값은없어도됨 => 이경우 0으로초기화 XCount anx; enum up, down ; namespace NS int var; namespace NAnother = NS; // NAnother와 NS는동일한네임스페이스임 3 장더나은 C 로서의 C++ (2) 18
7. 선언과정의 정의이면선언이다 성립 O, 선언이면정의이다 성립 X 선언이지만정의가아닌경우 1 함수몸체를기술하지않은함수, 즉, 함수프로토타입 2 extern 변수. 단, 초기화구문을포함하면정의가됨 3 extern 함수. 단, 함수몸체를포함하면정의가됨 4 클래스또는구조체내에선언된 static 멤버변수 5 클래스명또는구조체명선언 ( 구조체전체를의미하는것이아님 ) 6 typedef 선언 7 using 선언 정의가아닌선언의예 extern int count; int func(int); struct Point; typedef int MyInt; using NS::var; 3 장더나은 C 로서의 C++ (2) 19
7. 선언과정의 컴파일이되기위해서는 ß 파일단위 파일내에사용하고자하는식별자의선언이 1번이상등장 여러번등장할경우식별자의타입은동일해야함 extern int count; extern int count; extern char count; // (O) 선언은 2번이상나올수있음 // (X) 링크가되기위해서는 ß 프로젝트단위 해당식별자에대한정의가소스파일들중어딘가에단한번등장 ODR(One-Definition Rule) int x; int x; // (X) 중복해서정의되어있음, C 언어에서는됨 int x = 5; int x = 3; // (X), C 언어에서도안됨 3 장더나은 C 로서의 C++ (2) 20
7. 선언과정의 다중파일프로그래밍에서 ODR 을위배하는예 g_var1, g_var2, sum 이 2 번정의됨 3 장더나은 C 로서의 C++ (2) 21
7. 선언과정의 다중파일프로그래밍에서 ODR 의달성예 #ifdef MYMAIN #define EXTERN #else #define EXTERN extern #endif header.h EXTERN int count; // MYMAIN 정의여부에따라 extern 추가또는삭제 struct Point int x; int y; ; main.cpp point.cpp #define MYMAIN #include "header.h" Point P1; count = 1; #include "header.h" void func(int a) Point P2; count = 5; 3 장더나은 C 로서의 C++ (2) 22
7. 선언과정의 ODR 의예외 프로그래밍의편의를위해다음에대한정의는 ODR을따르지않아도됨 구조체, 열거체, 인라인함수, 클래스, 템플릿 하나의소스파일내에는단한번의정의가와야됨 하나의프로그램내에는 2번이상정의가능 단, 구조가동일해야함 다음의경우에는서로다른구조체로인식 a.cpp : struct Point int x; int y; ; b.cpp : struct Point int x; ; 3 장더나은 C 로서의 C++ (2) 23
8. 객체지향프로그래밍 예 1 : LEGO Digital Designer 개별블록들을조립하여더큰구조물형성 개별블록을잘만들어놓는다면! 3 장더나은 C 로서의 C++ (2) 24
8. 객체지향프로그래밍 예 2 : 컴퓨터조립 메인보드, CPU, 메모리, 그래픽카드, 사운드카드, 하드디스크 기존부품을새로운부품으로교체가능 à 인터페이스만같다면 객체지향프로그래밍 데이터추상화 (data abstraction) à 추상데이터형 데이터와메서드로구성됨 C++ 에서의추상데이터형 : 클래스 à 생성된변수 : 객체 ü 레고 : 클래스 블록을찍어내는틀, 객체 각블록 ü 컴퓨터 : 클래스 부품을찍어내는틀, 객체 각부품 상속 (inheritance) 컴퓨터 : 기존부품과유사한새로운부품을만들경우 ü 기존부품의기능을그대로유지하고추가또는변경된부분만수정 ü 기존부품도동작하고새로운부품도동작함 3 장더나은 C 로서의 C++ (2) 25
8. 객체지향프로그래밍 객체지향프로그래밍 ( 계속 ) 다형성 (polymorphism) 컴퓨터 : 부품 A 로부터상속받아부품 B, 부품 C 를만든경우, 모두 f 라는기능을가지고있다. 메인보드입장에서는 A 에대한 f 를수행하면실제부품이 A, B, C 냐에따라각부품에맞는 f 가수행되도록하고싶다. 동적바인딩기술적용 C++ 의일반화프로그래밍 (generic programming) 객체지향프로그래밍과는또다른특징 하나의함수나클래스가특정타입에구속되지않고다양한타입에적용될수있도록하는것 방법 : 템플릿 교재의구성 클래스와객체 : 4~7 장 상속 : 8 장 다형성 : 9 장 템플릿 : 10 장 3 장더나은 C 로서의 C++ (2) 26