본문 바로가기
프로그래밍 언어/C++

C++ 2단원 복습!

by 조엘 2020. 3. 11.

안녕하세요. 파피몬입니다.

 

이 복습 내용은 최호성 선생님의 "이것이 C++이다"를 공부하고 작성하였습니다. 

아직 모르는 게 많은 학생이라 오개념이 있을 수 있습니다. 친절하게 댓글로 알려주시면 좋은 공부 될 것 같습니다!!

2단원에서는 1단원에 이어서 C언어와 C++의 차이점에 주안을 두고 공부하였습니다. 

 

Chapter 2. C++ 함수와 네임스페이스

 

1. C++에서는 C언어와 달리 다형성(함수를 여러형태로 구현하고, 동시에 존재하는 것)을 지원한다. 고로 이름이 같지만 매개변수가 다른 함수를 정의할 수 있다. 이를 다중 정의(overloading)이라고 한다. 

 

 

2. C++에서는 디폴트 매개변수를 지원한다. 함수 원형의 선언부디폴트 값을 기술한다. 반드시 오른쪽 매개변수부터 기술해야 하며, 중간에 빼먹는 매개변수가 있으면 안된다!

 

 

3. 위의 다중 정의와 디폴트 매개변수가 조합된다면 '모호성'이 발생할 수 있다! 그럼으로 다중 정의는 함수 템플릿으로 대체하고, 디폴트 매개변수는 사용을 지양하는 편이 현명하다!

#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)
    return 0;
}

 

 

4. 함수 템플릿으로 사용자의 편의성과 확장성을 얻을 수 있다! caller함수가 변수의 형식을 결정한다. 디버거에서는 마치 해당변수가 이미 들어가 있는 형식으로 작동한다. 

#include<iostream>
using namespace std;

template<typename T>
T TestFunc(T a)
{
    cout<<"매개변수 a: "<<a<<endl;
    return a;
}

int main()
{
    //디버거에서는 int TestFunc(int a)로!
    //TestFunc<int>(3)으로 형 지정도 가능하다!
    cout<<"int\t"<<TestFunc(3)<<endl;
    
    //디버거에서는 double TestFunc(double a)로!
    //TestFunc<double>(5.3)으로 형 지정도 가능하다!
    cout<<"double\t"<<TestFunc(5.3)<<endl;
    return 0;
}

 

 

5. C++에서 재정의, 다중정의 등으로 함수의 이름을 중복해서 쓸 수 있게 하는 것 같지만, 실질적으로 컴파일을 돌려보면 Name Mangling이 적용되어 함수의 본명(?)은 겹치지 않게 선언이 알아서 된다. 

//컴파일러를 돌려보면 (괄호)안에 있는 부분이 함수의 본명이다
"int __cdecl Add(int, int)" (?Add@@YAHHH@Z)  

//이를 피하려면 extern "C"를 도입하여 C언어의 방식으로 함수를 컴파일 할 수 있다
//이 말은 곧 이름이 같은 함수는 컴파일 에러를 일으킨다는 뜻이다

extern "C"
{
    //둘다 이름이 Add임으로 컴파일 에러!
    int Add(int a, int b);
    double Add(double a, double b);
}

 

 

6. namespace는 C++의 변수/함수/클래스 등을 하나의 소속으로 묶어준다. 이름의 중복 가능성으로 인한 혼동을 방지하며, 이는 규모가 큰 프로그램에서 용이하게 써먹을 수 있다. 

 

 

7. using이라는 예약어를 통해 **소속::** 을 나타내주는 것 생략할 수 있다. 

#include<iostream>
//std::cout -> cout 표현가능!
using namespace std;

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

using namespace TEST;

int main()
{
    //TEST::라고 범위 지정 할 필요X
    TestFunc();
    cout<<g_nData<<endl;
    
    return 0;
}

--------------------
TEST::TestFunc()
100

 

 

8. namespace는 중첩이 가능하여, 큰 소속과 그 안의 소속에 각각 같은 이름으로 변수를 선언 할 수 있다. 정확한 변수에 접근하기 위해서는 정확한 소속을 써주는 것이 중요하다!

 

 

9. 전역함수/전역변수와 namespace에서의 함수/변수 이름이 동일하다면, 각각의 namespace를 함수/변수 호출 전 기술함으로써 각각을 구별해 호출한다.

 ** 위 같은 상황에서 해당 namespace에 using예약어를 선언한다면 '모호성'으로 인한 컴파일 에러 발생!

 ** 전역함수/전역변수를 호출 시 정확한 방법은 앞에 ::을 추가하여 ::전역함수 / ::전역변수 형식으로 기술하는 것!

 

 

10. 혼동되는 식별자 검색 순서

 ** 전역변수의 경우 선언 순서를 생각해야 한다. 만약 같은 scope에서 변수 호출 전에 변수가 선언이 되어있다면, 그 변수를 호출하고, 그렇지 않다면 그 다음 scope를 탐방해야 할 것! C언어의 전역변수와 비슷하다. 

#include<iostream>
using namespace std;

int nData = 200;

namespace TEST
{
    int nData = 100;
    void TestFunc(void)
    {
    	cout<<::nData<<endl;
    	cout<<nData<<endl;
    }
}

int main()
{
    TEST::TestFunc();
    return 0;
}

--------------------
200
100

 

#include<iostream>
using namespace std;

int nData = 200;

namespace TEST
{
    void TestFunc(void)
    {
    	cout<<::nData<<endl;
    	cout<<nData<<endl;
    }
    int nData = 100;
}

int main()
{
    TEST::TestFunc();
    return 0;
}

--------------------
200
200
반응형

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

C++ 4단원 복습! (2편)  (0) 2020.03.15
C++ 4단원 복습! (1편)  (0) 2020.03.14
C++ 3단원 복습! (2편)  (0) 2020.03.12
C++ 3단원 복습! (1편)  (0) 2020.03.12
C++ 1단원 복습!  (0) 2020.03.10

댓글