[1편] C언어 기반의 C++

헤더 파일 선언문 #include <iostream>

- 입출력을 위해서 필요한 헤더파일이다

- 표준 헤더파일의 선언에서는 확장자를 생략 할수 있다

( C언어와 마찬가지로 .h를 사용하지만 생략 )

 

함수 오버로딩

- C언어에서는 동일한 이름의 함수가 정의되는 것을 허용하지 않는다

- 함수 호출 시 전달되는 인자를 통해서 호출하고자 하는 함수의 구분이 가능한데, C++에서는 이러한 형태의 함수 정의를 함수 오버로딩이라고 한다

# C++에서는 호출할 함수를 찾을때, 함수의 이름, 매개변수의 선언의 정보를 이용해 찾는다 

# C에서는 함수의 이름만 이용해서 호출대상을 찾는다

 

void MyFunc(int n) { . . . }
int Myfunc(int n) { . . . }

 

위와 같이 함수의 이름과 매개변수의 선언이 같고 반환형만 다르다고 해서, 함수의 오버로딩이 될수 없다

 

매개변수의 디폴트 값

int MyFunc(int num=7) { return num+1; }

 

- 함수호출 시 인자를 전달하지 않으면 7이 전달된것으로 간주하겠다 라는 의미이다

- 매개변수에 디폴트 값이 설정되어 있으면, 선언된 매개변수의 수보다 적은 수의 인자 전달이 가능하다

다만, 전달되는 인자는 왼쪽에서부터 채워져 나가고, 부족분은 디폴트 값으로 채워진다

 

#include <iostream>

int MyFunc(int num = 1);
int MyFunc(int num) { return num+1; }

 

- 위와 같이 매개변수의 디폴트 값은 함수의 원형 선언에만 위치 시켜야한다

 

#include <iostream>

int MyFunc(int num, int num1 = 1) { return num+num1; }

 

- 디폴트 값은 반드시 오른쪽 매개변수의 디폴트 값부터 채우는 형태로 정의해야한다

- int MyFunc(int num = 1, int num1 ) { ... } -> 이런식의 정의는 유효하지 않다

# 함수에 전달되는 인자가 무조건 왼쪽에서부터 오른쪽으로 채워지기 때문이다!

( num = 1의 의미를 가지려면, 인자가 num1으로 가야하는데 함수에 전달되는 인자는 num부터 오른쪽으로 채워진다 )

 

인라인 함수

- 매크로 함수는 일반적인 함수에 비해서 실행속도의 이점이 있다

- 전처리 과정을 거치면, 함수의 몸체부분이 함수의 호출문을 대체한다

 

-> 매크로 함수는 정의하기가 복잡하니 일반 함수처럼 정의했으면 좋겠다 해서 나온 인라인 함수

inline int SQUARE(int x)
{
	return x*x;
}

 

- 매크로 함수는 전처리기에 의해서 처리되지만 ( #define ) 키워드 inline를 이용한 함수의 인라인화는 컴파일러에 의해서 처리가 된다

# 컴파일러가 인라인화가 오히려 성능에 해가 된다고 판단하면, 키워드를 무시한다

- 매크로 함수는 자료형을 적지 않으므로, 자료형에 의존적이지 않지만, 인라인 함수는 자료형을 적어야 하므로, 약간의 단점이 있다 ( 다만 template 를 사용해 이러한 단점 극복 가능 )

 

 

이름 공간 ( namespace )

- 프로그램이 대형화 되면서 함수 이름, 변수 이름 충돌 현상이 자주 발생해 이 문제를 해결하기 위해 등장

 

namespace Best
{
    int func1()
    {
    	return 1;
    }
}

int main(void)
{
    Best::func1();
    return 0;
}

 

- Best가 이름공간의 이름

- Best 이름을 가지고 있는 func1 함수를 호출하려면, Best::func1() 로 호출하면 된다

- ::는 범위 지정 연산자라고 한다

 

namespace Best
{
    int func1();
}

Best::func1()
{
    return 1;
}

 

- 함수의 선언은 헤더파일에, 함수의 정의는 소스파일에 저장한다

- 동일한 이름공간에 정의된 함수를 호출할때는 이름공간을 명시할 필요가 없다

- 이름공간은 다른 이름공간 안에 삽입 될수 있다 ( Parent::SubOne::num ) 이런식으로 사용가능 !

 

-> 즉 std::cout 또는 std::cin 와 같은 정체는 std라는 이름공간 안에 선언된 cout, cin를 의미한다

( iostream 에 선언되어 있는 cout, cin )

 

매일 std:: 와 같은 이름공간을 명시하기에는 분명히 귀찮을 수 있다

-> using 를 이용해 이름공간을 명시하면 이름 공간을 지정하지 않고 호출하겠다 라는 의미를 가진다

 

namespace Best
{
    int func1()
    {
    	return 1;
    }
}

int main(void)
{
    using Best::func1; // 또는 using namespace Best; 도 가능하다!
    func1();
    return 0;
}

 

- Best::func1 는 특정 이름하나만, using namespace Best;는 이름 공간 전체를 가져오는 것을 의미한다

 

이름 공간이 너무 중첩이 심해지면, 아래와 같이 별칭을 줄수도 있다

 

AA::BB::CC::num1 = 30;
namespace ABC= AA::BB::CC;

ABC::num1 = 30;

 

- 전역변수는 지역변수에 가려지는 특징이 있는데, 전역변수를 사용하고 싶을때는 ::를 사용하면 된다

int val = 1;

int func(void)
{
   int val = 20;
   val = 30; // 지역변수 val이 30으로 설정
   ::val += 1; // 전역변수 val이 1 증가
}

 

 

윤성우의 『C++ 열혈 프로그래밍』에서 중요한 내용을 발췌하여 정리한 글입니다.

 

'C++' 카테고리의 다른 글

C++ 임시객체에 대해서  (2) 2025.01.15
C++ CRT 라이브러리로 메모리 누수 찾기  (0) 2025.01.14
C++ friend 키워드  (0) 2025.01.14
C++ 참조 ( Reference )  (0) 2025.01.14
C++ 포인터 ( Pointer )  (0) 2025.01.14
  Comments