💙ref.
스콧 마이어스, Effective C++ [3판], 곽용재(역), 프로텍미디어, 2015
1. C++기본 용어
1.1. 선언
선언 (declaration)
- 코드에 사용되는 ‘어떤 대상’의 이름과 타입을 컴파일러에게 알림
- 구체적인 세부사항은 기재하지 않음
[code] declaration example
1
2
3
4
5
6
7
extern int x; // 객체 선언
std::size_t numdigits(int number); // 함수 선언
class Widget; // 클래스 선언
template<typename T> // 템플릿 선언
class GraphNode;
-
int x
: built-in(기본제공) 타입도 ‘객체’에 포함 -
std namespace
: C++의 표준 라이브러리 구성요소가 모두 포함된 네임스페이스- C의 라이브러리와 C++ 라이브러리에 공통된 기능 일부 내장
- 어떤 헤더를
#include
하느냐애 따라 라이브러리 결정
- 어떤 헤더를
- C의 라이브러리와 C++ 라이브러리에 공통된 기능 일부 내장
-
size_t
: 부호 없는 정수 타입을 typedef로 정의-
C++에서 개수를 셀 때 size_t 사용
eg) STL 컨테이너의 원소 개수 등
-
일반적으로
operator[]
함수를 개발자가 정의할 때도size_t
를 받도록 구현함
-
1.2. 시그너처
시그너처(Signature)
-
모든 함수의 선문에 나오는 매개변수 리스트와 반환 타입
-
numDigits
함수의 시그너처 :std::size_t(int)
eg)
int
하나를 취하고std::size_t
를 반환하는 함수
단, ‘시그너처’의 공식 C++ 정의에서는 함수 반환 타입을 제외한다! 편의성을 위해 포함했다고 말한다.
-
1.3. 정의
정의(Definition)
- 선언에서 빠진 구체적인 세부사항을 컴파일러에게 전달
- 컴파일러는 해당 객체에 대한 메모리 마련
- 정의 제공 기능
- 함수/템플릿 정의: 코드 본문 제공
- 클래스/템플릿 정의: 클래스 혹은 템플릿 멤버 제공
[code] definition example
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
int x; // 객체 정의
std::size_t numDigits(int number) // 함수 정의
{
std::size_t digitSoFar = 1;
while ((number/10) != 0) ++digitsSoFar;
// 반환 값: 매개변수에 들어 있는 숫자 개수
return digitsSoFar;
}
class Widget // 클래스 정의
{
public:
Widget();
~Widget();
...
};
template<typename T> // 클래스 템플릿 정의
class GraphNode
{
public:
GraphNode();
~GraphNode();
...
};
1.4. 초기화
초기화(Initialization)
- 어떤 객체에 최초의 값을 부여하는 과정
- 사용자 정의 타입으로 생성한 객체의 경우, 생성자에 의해 초기화
- 기본 생성자(Default Constructor)
- 어떤 인자도 주어지지 않은 상태로 호출될 수 있는 생성자
- 매개변수가 없거나 모든 매개변수가 기본 값을 갖고 있을 경우
- 어떤 인자도 주어지지 않은 상태로 호출될 수 있는 생성자
[code] Initialization example
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
// 기본 생성자
class A
{
public:
A();
};
// 기본 생성자
class B
{
public:
explicit B(int x = 0, bool b = true);
}
// 기본 생성자x
class C
{
public:
explicit C(int x);
}
explicit
: 선언된 생성자는 암시적인 타입 변환을 수행하는 데 쓰이지 않음- 개발자가 예상하지 못한 타입 변환 방지
- 암시적 타입 변환에 생성자가 사용되지 않는다면
explicit
선언을 적극 권장함!!
[code] explicit example
1
2
3
4
5
6
1. void doSomething(B bObject);
2. B bObj1;
3. doSomething(bObj1);
4. B bObj2;
5. doSomething(28);
6. doSomething(B(28))
B
타입의 객체를 하나 받는 함수B
타입의 객체B
객체를doSomething
으로 넘김int
인자 28로부터B
객체 생성- 에러!
doSomething
은B
를 취해야 함(단순int
x) B
클래스의 생성자로int
에서B
로 명시적 변환(캐스팅)
1.5. 복사 생성자
복사 생성자(Copy Constructor)
- 객체 초기화를 위해 같은 타입의 다른 객체로부터 초기화할 때 호출되는 함수
- 값에 의한 객체 전달을 정의하는 함수!
복사 대입 연산자(Copy Assignment Operator)
- 같은 타입의 다른 객체에 어떤 객체의 값을 복사하는 용도로 쓰이는 함수
[code] copy constructor 1
1
2
3
4
5
6
7
8
9
10
11
12
13
14
class Widget
{
public:
Widget(); // 기본 생성자
Widget(const Widget& rhs); // 복사 생성자
Widget& operator=(const Widget& rhs); // 복사 대입 연산자
...
};
Widget w1; // 기본 생성자 호출
Widget w2(w1); // 복사 생성자 호출
w1 = w2; // 복사 대입 연산자 호출
Widget w3 = w2; // 복사 생성자 (!= 복사 대입 연산자)
w1 = w2
!=Widget w3 = w2 // 복사 생성자 '='
- 새로운 객체가 정의되지 않은 상황에서 생성자 호출 불가능
- 복사 대입 호출
- 객체가 새로 정의될 때는 생성자가 호출
- 복사 대입 호출 불가능
- 새로운 객체가 정의되지 않은 상황에서 생성자 호출 불가능
[code] copy constructor 2
1
2
3
4
bool hasAcceptableQuality(Widget w);
...
Widget aWidget;
if(hasAcceptableQuality(aWidget)) ...
w
:hasAcceptableQuality
함수로 매개변수 값이 넘겨짐-
실제 호출에서
aWidget
=>w
로 복사- 복사 과정에서
Widget
의 복사 생성자 사용
=> *'값에 의한 전달(pass-by-value)'* : 복사 생성자 호출
- 복사 과정에서
-
1.6. STL
-
표준 템플릿 라이브러리
- 컨테이너, 반복자, 알고리즘 및 이들과 관련된 기능들이 집결한 결정체
- 해당 기능들이 함수 객체로 구현되어 있음
- 함수 객체는 함수 호출 연산자
operator()
를 오버로드한 클래스로 생성
- 함수 객체는 함수 호출 연산자
-
미정의 동작(undefined behavior)
-
C++으로 사용되는 구문 요소들 중 몇 개는 동작 자체가 정의되어 있지 않음
=> 실행 시간에 어떤 현상이 터질지 확실히 예측 불가능
-
미정의 동작을 일으키는 예제
1
2
3
4
5
6
7
8
9
10
11
12
int *p = 0; // p== 널포인터
// 널포인터를 역참조하면 미정의 동작 발생
std::cout << *p;
// name은 크기가 6인 배열임
// 문자열 배열은 반드시 마지막 널문자 고려할 것!!
char name[] = "Darla";
// 유효하지 않은 배열 원소지정번호로 참조하려고 하면 미정의 동작 발생
char c = name[10];
+) C++에서는 인터페이스 기능을 제공하고 있지 않지만 순수 가상 함수를 통해 인터페이스 기능을 구현할 수 있다.
- 클라이언트(client)
- 인터페이스를 사용하는 대상
- 함수를 호출하는 코드, 코드를 작성했거나 유지보수하는 사람 등
- 인터페이스를 사용하는 대상
2. 교재 참고사항
2.1. 이름짓기에 대한 규약
- 좌변과 우변의 약자를 각각
lhs
,rhs
로 지정- 일반적으로 이항 연산자(
operator==
,operator*
등)를 구현하는 함수의 매개변수로 쓰임- eg)
operator*(a, b)
=>const Rational operator*(const Rational& lhs, const Rational rhs)l
- eg)
- 일반적으로 이항 연산자(
- 포인터 이름 선언 시, 타입
T
의 객체에 대한 포인터를pt
로 작성- “T에 대한 포인터”
포인터 예제 코드
1
2
3
4
5
6
7
Widget *pw;
class Airplane;
Airplane *pa;
class GameCharacter;
GameCharacter *pgc
- 참조자에 대해서도 유사한 규칙 사용
- eg)
Widget
에 대한 참조자rw
- eg)
Leave a comment