갓똥
나는야 프로그래머
갓똥
전체 방문자
오늘
어제
  • 분류 전체보기 (186)
    • 프로그래밍 (146)
      • 자바 (9)
      • 안드로이드 (2)
      • 유니티 (20)
      • C++ (38)
      • C# (56)
      • HTML (2)
      • 파이썬 (3)
      • 자료구조 (2)
      • 알고리즘 (0)
      • 문제풀이 (4)
      • 디자인 패턴 (7)
      • 카카오톡 봇 (1)
      • 엑셀 (1)
      • 기타 (1)
    • 게임 (21)
      • 테일즈위버 (0)
      • 카이로소프트 (1)
      • 순위 (19)
      • 기타 (1)
    • 일상 (13)
      • 카페 (1)
      • 방탈출 (12)
    • 기타 (6)
      • 웃긴자료 (5)

블로그 메뉴

  • 홈
  • 방명록

공지사항

인기 글

태그

  • C# boxing
  • 롤 골드그래프
  • C++ 소멸자
  • pc게임 순위
  • C++ 상속
  • 게임 디자인 패턴
  • C# 예외 처리
  • 전세계 게임 매출
  • 모바일 게임 순위
  • 게임 매출 순위
  • c# delegate
  • 자바
  • c# coroutine
  • C++ virtual
  • 유니티 그래프 그리기
  • pc 게임 순위
  • 유니티 그래프
  • Unity Graph
  • 2020년 게임 매출
  • 강남 방탈출
  • c# 코루틴
  • 게임매출순위
  • c# collection
  • 글로벌게임매출
  • C++
  • 유니티 골드그래프
  • c# Thread
  • 알고리즘
  • c# unboxing
  • 전세계게임매출순위

최근 댓글

최근 글

티스토리

hELLO · Designed By 정상우.
갓똥

나는야 프로그래머

[C++] C언어와 다른 C++ 함수(1)
프로그래밍/C++

[C++] C언어와 다른 C++ 함수(1)

2019. 10. 9. 22:18
728x90
반응형

1. default parameter

 - 함수 호출 시 인자를 전달하지 않으면 미리 지정된 인자값을 사용할 수 있다.

void move(int x, int y = 0, int z = 0) {

}

int main() {
    move(1, 2, 3);
    move(1, 0, 0);
    move(1);    // 1, 0, 0
    move(1, 10) // 1, 10, 0
}

 - 함수의 마지막 인자부터 차례대로 디폴트 값을 지정해야 한다.

void move(int x = 0, int y) { } // error

int main() {
    move(3); // y에 3이 적용될 것인가?
}

//----- 예시 ------
void t1(int a,     int b,     int c = 0) { }  // ok
void t2(int a,     int b = 0, int c = 0) { }  // ok
void t3(int a = 0, int b = 0, int c = 0) { }  // ok

void t4(int a = 0, int b,     int c    ) { }  // error
void t5(int a = 0, int b,     int c = 0) { }  // error
void t6(int a,     int b = 0, int c    ) { }  // error

 - 함수를 선언과 구현으로 분리 할 때는 함수 선언부에만 디폴트 값을 표기해야 한다.

void main(int x, int y);

int main() {
    move(1, 2); // ok
    move(1);    // 인자가 두개인데 하나만 보냈으니 error
    move();     // 마찬가지 이유로 error
}

void move(int x = 0, int y = 0) {

}

 - 위의 코드에서 구현부에서 default로 정한 인자를 선언부에 적으면 error를 없앨 수 있다.

 


2. function overloading

 - C언어에서는 동일한 이름의 함수를 2개 이상 만들 수 없다.

 - C++언어 에서는 동일한 이름의 함수를 여러 개 만들 수 있다.

  => 단, 함수 호출 시 구별할 수 있도록, 인자의 개수나 인자의 타입이 달라야 한다.

 - 함수 사용자 입장에서는 동일한 함수처럼 생각하게 되므로 일관된 형태의 라이브러리를 구축할 수 있다.

 - C언어를 제외한 대부분의 최신 언어들이 지원하는 특징(Java, C++, C#, Swift 등)

int rect(int a, int b) {
    return a * b;
}

double rect(double a, double b) {
    return a * b;
}

int main() {
    rect(1, 2);   // 위의 함수를 호출
    rect(3.4, 5.6); // 아래의 함수를 호출
}

 - 인자의 개수가 달라도 디폴트 값이 있는 경우는 주의 해야 한다.

 - 함수 반환 타입만 다른 경우는 오버로딩 될 수 없다.

 - 정수타입과 포인터 타입에 대한 오버로딩은 에러는 없지만 사용하지 않는 것이 좋다.

void t1(int a)    { }
void t1(double a) { }  // ok

void t2(int a) { }
void t2(int a, int b) { } // ok

void t3(int a) { }
void t3(int a, int b = 0) { } // error
//t3(10); - 둘 중 무슨 함수를 호출해야 할지 모른다.

int    t4(int a) { return 0; }
double t4(int a) { return 0; } // error
//t4(10); - 반환 타입만 다른 경우 무엇이 호출 될 지 몰라 error

void t5(int   n) { }
void t5(char* s) { } // ok 이긴 하지만... 가독성이 떨어짐
//t5(0); - 포인터 변수를 초기화할 때 0을 쓸수도 있지만, 0은 정수이므로 int n으로 호출됨
//t5((char*)0); - 아래함수를 부를 수 있음
//t5(nullptr);  - 아래 함수를 부를 수 있음 C++11부터 사용가능

 


3. template

 - 타입만 다르고 구현이 동일하거나 유사한 함수가 여러개 있다면 직접 만들지 말고, 컴파일러가 함수를 생성하게

 - 컴파일러가 함수를 생성할 때 사용할 함수의 틀(template)이 있어야 한다.

 - 개발자는 함수 템플릿을 만들고, 컴파일러가 템플릿을 사용해서 필요한 함수를 생성하게 한다.

 

template<typename T> // 틀을 만듬. T대신 다른 문자를 넣어도 되지만 관례상 T를 많이 씀.
T rect(T a, T b) {
    return a * b;
}

/*
double rect(double a, double b) {
    return a * b;
}
*/

int main() {
    rect<int>(1, 2);        // int rect(int a, int b)
    rect<double>(3.4, 5.6); // double rect(double a, double b)
}

 - 함수가 아닌 함수를 만드는 틀(template)

 - 템플릿을 사용하는 코드를 보고 컴파일러가 컴파일 시간에 필요한 타입의 함수를 생성

 - 컴파일 된 기계어 코드에는 int, double 버전의 rect 함수가 따로 존재

//template<class T>
template<typename T> // template parameter
T rect(T a, T b) {   // call parameter
    return a * b;
}

int main() {
    rect<int>(1, 2);
    rect<double>(3.4, 5.6);
    
    rect(1, 2);
    rect(3.4, 5.6);
}

3.1 template parameter

    => 컴파일 시간에 전달되어서 함수가 생성

    => 함수가 생성되는 과정을 템플릿 인스턴스화(tempate instantiation)이라고 한다.

3.2 call parameter

    => 실행시간에 함수에 전달

 - template parameter를 표기할 때 typename 또는 class 키워드 사용가능 (요즘은 typename 사용 추세)

 - 함수 템플릿 사용시 타입을 명시적으로 지정하지 않으면 함수 호출 인자를 보고 컴파일러가 결정(type deduction, 추론/연역)

template<typename T>
struct Point {
    T x;
    T y;
};

int main() {
    Point<int> pt;
    
    pt.x = 1;
    pt.y = 1;
    
    Point<double> pt2;
    
    pt2.x = 1.2;
    pt2.y = 3.4;
}

3.3 클래스(구조체) 템플릿

 - 함수 뿐 아니라 클래스(구조체)도 템플릿으로 만들 수 있다.

 - C++17 부터는 생성자가 있으면 템플릿 파라미터 전달을 생략할 수 도 있다.

 


4. inline function

 - 함수 반환 타입 앞에 inline을 표기한 함수

 - 함수 호출 시 함수로 이동하지 않고 함수의 기계어 코드를 치환 한다.

 - 장점

    => 실제 함수 호출 보다 빠르다.

 - 단점

    => 치환되는 함수가 큰 경우 목적 코드가 커질 수 있다.

int add1(int a, int b) {
    return a + b;
}

inline int add2(int a, int b) {
    return a + b;
}

int main() {
    int n1 = add1(1, 2); // 호출
    int n2 = add2(3, 4); // 치환
}

4.1 컴파일러와 인라인

 - 어셈블리 소스 코드를 확인 하는 방법

    => cl 컴파일러 : cl 소스이름.cpp /FAs  ->  소스이름.asm

    => g++ 컴파일러 : g++ 소스이름.cpp -S  -> 소스이름.s

 - 인라인 함수의 실제 치환 여부는 컴파일러 종류, 컴파일 옵션, 함수 크기등에 따라 달라진다.

    => cl 컴파일러의 경우는 /Ob1 옵션 사용 시 치환 적용

    => g++은 -fno-inline , -finline-small-functions , -findirect-inlining 등 수많은 옵션이 존재

어셈블리 코드

 - 호출의 경우 5줄의 코드가 나옴 (push ~ mov)

 - 치환은 2줄 (move ~ add)

 - 작은 함수는 치환이 목적 코드를 줄일 수 있다.

728x90
반응형

'프로그래밍 > C++' 카테고리의 다른 글

[C++] range for / if init / if constexpr  (0) 2019.10.18
[C++] C언어와 다른 C++ 함수(2)  (0) 2019.10.11
[C++] 변수(2)  (0) 2019.10.05
[C++] 변수(1)  (0) 2019.10.05
[C++] iomanipulator  (0) 2019.10.05
    '프로그래밍/C++' 카테고리의 다른 글
    • [C++] range for / if init / if constexpr
    • [C++] C언어와 다른 C++ 함수(2)
    • [C++] 변수(2)
    • [C++] 변수(1)
    갓똥
    갓똥
    공부하며 알아가는 내용을 정리해 봅니다.

    티스토리툴바