이것이 C++이다 : Chapter2 내용 정리

JB·2022년 5월 2일
0
post-thumbnail

C++ 사용 2년차의 입문서 완독기 시작합니다...Drop the Beat

디폴트 매개변수

C언어와 다른 점 : 함수 선언 시 디폴트 매개변수를 지정하여 실인수를 경우에 따라 생략 기술할 수 있다.

#include <iostream>
using namespace std;

int TestFunc(int nParam = 10){
    cout<<nParam<<endl;
}

int main(){
    TestFunc();
    TestFunc(20);
}

/*출력결과
10
20
*/

*주의

  • 매개변수는 오른쪽부터 디폴트값을 지정해야함. 중간에 빼먹을 수 없음.
  • 호출자함수가 피호출자 함수 매개변수의 실인수를 명시할 때 왼쪽부터 짝을 맞추어 적용하며 짝이 맞지 않는 매개변수는 디폴트값이 들어간다.
  • 함수 원형을 수정할 때에는 디폴트 매개변수로 기존의 사용(호출)코드에 에러가 생기지 않도록 할 수 있다. ex) 아래 코드. 만약 Calc_modified()는 Calc()에 내용을 추가한 것이라고 가정(Calc는 없음!). nType을 디폴트 매개변수로 선언하지 않는다면 기존 코드는 에러가 뜰 것 ㄴ C++은 객체지향함수이므로 제작자가 함수 사용자를 고려해 코드를 작성해야함.
#include <iostream>
using namespace std;

int Calc(int nWidth, int nHeight){
    return nWidth * nHeight;
}

//위의 함수를 아래와 같이 수정했다고 가정. 오버로딩 표현한 거 아님
int Calc(int nWidth, int nHeight, int nType = MYTYPE_A){
    return nWidth * nHeight + nType;
}

int main(){
    Calc(10,5); //기존 코드
    Calc_modified(10, 5, MYTYPE_A); // 수정 후 코드
}
  • 구글 스타일 가이드에서는 사용자가 해당 함수 형태를 추측하기 어려움으로 모호성이 생겨날 가능성이 커서 필수를 제외하고는 디폴트 매개변수 사용을 지양함.
  • 다형성을 지원하는 언어에서는 사용(Call) 주의!

함수 다중 정의

Overloading. 이름은 같지만 내용이 다른 것을 여러 개 정의할 수 있음(Name Mangling : 컴파일 단에서 오버로드한 함수 이름을 각각 시그니처 이름으로 바꿔서 컴파일함. 따라서 오버로드 지원가능)

C언어에서는 허용하지 않지만 C++은 다형성을 지원함.

다만 컴파일러에 의해 호출되는 함수가 결정되므로 모호성이 증가(여기에 디폴트 매개변수까지 쓰면 모호성 더 커짐) → 유지보수ㅠㅠ

ex) 주의 : 함수를 만든 제작자는 오류X, 사용자는 오류를 경험

#include <iostream>
using namespace std;

void TestFunc(int a){
    cout<<"TestFunc(int)"<<endl;
}

void TestFunc(int a, int b=10){
    cout<<"TestFunc(int, int)"<<endl;
}

int main(){
    TestFunc(5); //오류
}

따라서 템플릿 사용을 추천!

호출자에 의해서 타입이 정해지므로 모호성은 줄어들고 같은 일을 하는 코드가 여러번 등장X → 안정적!

#include <iostream>
using namespace std;

template <typename T>
T add(T a, T b){
    return a+b;
}

int main(){
    cout<<add(3, 4)<<endl;
    cout<<add(3.3, 5.5)<<endl;
}

/* 출력결과
7
8.8
*/

인라인 함수

매크로 함수와 함수의 장점을 모두 가진 함수

사용시 함수 앞에 ‘inline’을 추가

함수를 사용하면 내부적으로 여러 연산들로 인해 스택 메모리 사용이 증가함. 이를 극복하고자 매크로를 사용하지만 함수가 아니므로 논리적 오류를 발생시키고 매개변수 형식을 지정할 수 없음

다만 코드 길이가 일정 수준 이상이면 인라인 함수를 쓰지 않는 것이 좋음

Visual Studio 에서 최적화>인라인함수 확장>기본값 을 사용하면 인라인 함수로 적합한 함수는 모두 인라인 함수로 만들 수 있음

*강의자 추천 : <독하게 시작하는 C> 16장 전처리기 강의

네임스페이스

C++의 요소들을 한 범주나 소속으로 묶어주는 문법

namespace 예약어{} 로 사용한다.

전역 요소는 전역 네임스페이스 혹은 무소속이라고 생각할 수 있다.

#include <iostream>
using namespace std;

namespace Test{
    int g_nData = 100;
    
    void TestFunc(void){
        cout<<"Test::TestFunc()"<<endl;
    }
}

using namespace Test;

int main(){
    TestFunc();
    cout<<g_nData<<endl;
}
/* 출력결과
Test::TestFunc()
100
*/

네임스페이스 중첩 가능

같은 이름의 네임스페이스를 using 선언하면 함수가 오버로드 되어 모호해지고 오류가 난다!

식별자 검색 순서

식별자가 선언된 위치를 검색하는 순서

💡 전역함수인 경우
  1. 현재 블록 범위

  2. 현재 블록을 포함하고 있는 상위 블록 범위

  3. 가장 최근에 선언된 전역 변수나 함수(선언순서) : 같은 네임스페이스라도 전역변수에서 먼저 선언이 되었으면 동일 네임스페이스 변수가 아닌 전역변수를 검색함

  4. using 선언된 네임스페이스 혹은 전역 네임 스페이스. 단, 두 곳에 동일 식별자가 존재할 경우 오류

💡 클래스 메소드인 경우
  1. 위의 1번

  2. 위의 2번

  3. 클래스 멤버

  4. 부모 클래스 멤버

  5. 위의 3번

  6. 호출자 코드가 속한 네임스페이스의 상위 네임스페이스

  7. 위의 4번

profile
자율주행 이동체를 배우고 있는 JB입니다.

0개의 댓글