목차
- C++ STL(Standard Template Library)에 대해 배워보자
- Chap01 : 연산자 오버로딩
- Chap02 : 함수 포인터
- Chap03 : 함수 객체
- Chap04 : 템플릿
- Chap05 : STL 소개
- Chap06 : 시퀀스 컨테이너
- Chap07 : 연관 컨테이너
- Chap08 : 알고리즘
- Chap09 : STL 함수 객체
- Chap10 : 반복자
- Chap11 : 컨테이너 어댑터
- Chap12 : String 컨테이너
- 참고하면 좋은 내용들
해당 글은
최호성 저자이것이 C++이다도서를 참고하여 작성되었습니다.
해당 코드는 다음과 같은 환경에서 실행되었습니다.
개발 환경 : M2 Macbook Pro 14,Sonoma 14.0
IDE :CLion
Language Standard Version :C++17
들어가며
Chap01을 설명하면서 상수형 객체와 메서드에 대해 매우 중요한 부분이라 따로 짚고 넘어간다 했었는데요. 이번 글에서 상수, 상수형 객체, 상수형 메서드가 무엇인지, 그리고 왜 사용하여야 하는지, 주의해야할 점과 중요한 점은 무엇인지 한번 다루어 보도록 하겠습니다! 깃허브에 작성된 코드는 따로 없고, 본문에 있는 코드 참고해주시면 되겠습니다!
중요 포인트는요!
지금과 같이
노란색 박스에는주의사항이초록색 박스에는팁 / 참고사항이 있으니
꼭 읽어보시길 권합니다!중요한 내용이 담겨 있습니다!!
01. const 키워드
먼저 const 키워드에 대해 알아보겠습니다. const 키워드는 값을 상수로 지정하는 키워드로 프로그래머가 수정하지 못하도록 컴파일러에 지시합니다. 선언과 동시에 초기화 해야하며, 초기화 이후에는 값을 변경할 수 없습니다. 만약 객체의 값이 변경되면 안되는 상황에 쓰면 매우 유용합니다. 사용자, 개발자의 실수를 방지할 수 있으니까요.
사용하는 방법은 정말 간단합니다. 자료형 타입 앞에 const 선언을 해주면 됩니다. 그럼 const 키워드를 어떻게 사용하는지에 대해 알아보겠습니다.
const 비 멤버 변수
일반적으로 클래스 내부의 멤버 변수가 아닌 경우의 const 변수입니다. 사용 방법은 비교적 간단합니다.
1
2
3
4
const int a = 10;
int const a = 10; // 위와 같은 의미
// a = 20; error: read-only variable is not assignable
위 코드에서 단순히 int 자료형 앞에 키워드를 붙여주면 됩니다. const 선언이 붙은 이 객체는 상수가 되며, 값을 변경할 수 없게 됩니다.
아래에 있는 int const도 동일한 의미를 지니고 있으나, 보통 const int 라는 표현을 많이 사용합니다.
const 멤버 변수
클래스 내부에 정의된 const 멤버 변수의 사용 방법입니다.
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
28
#include <iostream>
using namespace std;
class Test
{
const int num; // 1. 생성자 초기화 리스트 사용
const int num2 = 10; // 2. 선언 및 초기화 사용(C++11 부터 사용 가능)
public:
Test(int n)
: num(n)
{
}
void Print() const
{
cout << num << endl;
cout << num2 << endl;
}
};
int main()
{
Test t(10);
t.Print();
return 0;
}
const 키워드는 선언과 동시에 초기화 해야된다고 앞서 말씀 드렸었는데요. 클래스 내부에 멤버 변수로 정의되어 있을 경우 다음과 같이 사용이 가능합니다.
생성자 초기화 리스트 사용const int num = n;과 동일합니다.- class 내부에서
const int num을 정의한 것은 객체 생성시 메모리 할당과 동시에 초기화 리스트가 호출되어 초기화가 가능합니다. - 즉, class 내부에 정의된 상수 멤버 변수는 초기화 리스트가 아닌 함수나 생성자 안에서 초기화 될 수 없습니다.
선언 및 초기화 사용(C++11 부터 사용 가능)const int num2 = 10;과 같이 선언과 동시에 초기화가 가능합니다.- class 생성자 호출시 초기화 되는 것이 아닌 프로그램 실행시 초기화 됩니다.
const 포인터 변수
그럼 다음과 같은 코드는 어떨까요?
1
2
3
4
5
int num = 10;
const int* a = # // 1. pointer to constant (상수 지시 포인터)
int* const b = # // 2. constant pointer (상수 포인터)
const int* const c = # // 3. constant pointer to constant (상수 지시 상수 포인터)
정말 어지럽죠.. 포인터만 해도 어려운데 상수 선언까지 양옆으로 되어 있으니 뭐가 뭔지 구분하기 어렵습니다.
1. pointer to constant (상수 지시 포인터)
const int* a = #는 상수 지시 포인터로 포인터가 가리키는 값 자체가 상수임을 뜻합니다.
즉, 가리키는 값 자체인 int num = 10;이 상수는 아니지만, 가리키는 값을 변경하지 못한다는 뜻입니다.
단, 포인터 주소 자체는 바꿀 수 있습니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include <iostream>
using namespace std;
int main()
{
int num = 10;
int num2 = 20;
const int* a = #
cout << *a << endl;
a = &num2;
cout << *a << endl;
// *a = 20; error: read-only variable is not assignable
return 0;
}
[출력 결과]
10
20
2. constant pointer (상수 포인터)
int* const b = #는 상수 포인터로 포인터의 주소값이 상수임을 뜻합니다.
위의 경우와는 반대로 가리키는 값 자체인 int num = 10;을 변경할 수 있지만, 포인터 주소 자체는 변경하지 못합니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include <iostream>
using namespace std;
int main()
{
int num = 10;
int num2 = 20;
int* const b = #
cout << *b << endl;
*b = 20;
cout << *a << endl;
// b = &num2; error: cannot assign to variable 'b' with const-qualified type 'int *const'
return 0;
}
[출력 결과]
10
20
3. constant pointer to constant (상수 지시 상수 포인터)
const int* const c = #는 상수 지시 상수 포인터로 위 두가지 경우를 합친 것과 같습니다.
즉, 포인터가 가리키는 값의 변경이 불가능하며, 포인터의 주소 또한 변경이 불가능합니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include <iostream>
using namespace std;
int main()
{
int num = 10;
int num2 = 20;
const int* const c = #
cout << *c << endl;
cout << *c << endl;
// *c = 20; error: read-only variable is not assignable
// c = &num2; error: cannot assign to variable 'c' with const-qualified type 'int *const'
return 0;
}
[출력 결과]
10
10
정리하자면 다음과 같습니다.
| 타입 | 포인터가 가리키는 값을 변경할 수 있는가? | 포인터의 주소를 변경할 수 있는가? |
|---|---|---|
| const int* a = &num | X | O |
| int* const b = &num | O | X |
| const int* const c = &num | X | X |
const 포인터 변수와 비슷한 자매품이 STL에 있는데요. 바로 반복자 입니다. 지금 자세히 알아보지는 않겠지만, 위의 경우와 비슷하다고 보시면 됩니다.
1
2
3
4
5
6
7
8
9
10
vector<int> v;
v.push_back(10);
v.push_back(20);
v.push_back(30);
vector<int>::iterator iter = v.begin();
vector<int>::const_iterator citer = v.begin();
const vector<int>::iterator iter_const = v.begin();
const vector<int>::const_iterator citer_const = v.begin();
지금은 가볍게 보기만 하고 넘어가시면 될 것 같습니다.
02. 상수형 메서드
상수형 메서드는 함수 원형 뒤에 const 키워드로 선언된 함수로 멤버 변수에 읽기 접근은 가능하지만, 쓰기는 허용되지 않는 메서드를 말합니다.
모든 멤버 변수들이 상수화 됩니다.
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
28
29
30
31
32
33
34
35
36
37
38
39
40
41
#include <iostream>
using namespace std;
class Test
{
public:
Test(int num)
: nData(num)
{
}
~Test() { }
// 상수형 메서드 선언 및 정의
int GetData() const
{
return nData; // 멤버 변수의 값을 읽을 수 있지만, 쓸 수는 없음.
}
void SetData(int n)
{
nData = n;
}
// 상수형 메서드 선언 및 정의
void Print() const
{
cout << GetData() << endl; // 상수형 메서드에서는 오직 상수형 메서드만 호출 가능!
}
private:
int nData = 0;
}
int main()
{
Test t(10);
t.Print();
return 0;
}
상수형 메서드로 정의된 GetData() 함수는 멤버 변수의 값을 변화하거나 변화를 일으킬 가능성이 없습니다. 또한, 상수화된 메서드가 아니라면 멤버 함수라 하더라도 호출이 불가능해집니다.
즉, 다음과 같은 코드는 허용되지 않습니다.
1
2
3
4
5
6
int GetData() const
{
SetData(20); // 상수형 메서드가 아닌 멤버 함수는 호출 불가 Error!
return nData; // 멤버 변수의 값을 읽을 수 있지만, 쓸 수는 없음.
}
위 코드를 실행시켜 보면 다음과 같은 에러가 발생합니다.
error: ‘this’ argument to member function ‘SetData’ has type ‘const Test’, but function is not marked const
여기서 중요한 점은
에러 메시지를 보면 “
SetData()를 호출한this포인터의의 타입은const Test인데,함수의 타입은 const가 아니다.” 라고 나와있습니다. 이를 통해 상수형 메서드의 특징을 알 수 있습니다.바로 상수형 메서드의 상수화 방법은
"this 포인터를 상수 지시 포인터(pointer to constant)로 변경하는 것"입니다. 아까 위에서 다룬 내용const 포인터 변수와 같이 this 포인터의 형식이Test *this;이 아닌const Test *this;라는 것 입니다.
따라서 다음과 같은 코드 역시 불가능합니다.
1
2
3
4
5
6
int GetData() const
{
nData = 20; // 멤버 변수의 값을 쓸 수 없음 Error!
return nData; // 멤버 변수의 값을 읽을 수 있지만, 쓸 수는 없음.
}
여기서 nData 는 this->nData와 같습니다. 하지만, this 포인터의 타입이 const Test* (상수 지시 포인터) 이기 때문에 포인터가 가리키는 값을 변경할 수 없게 됩니다.
결론은 다음과 같습니다.
상수형 메서드는 절대로(혹은 문법적으로)멤버 변수의 값을 쓸 수 없고,상수형 메서드가 아닌 멤버는 호출할 수 없다.
03. 상수형 객체
const 키워드가 붙은 객체. 바로 이것을 상수형 객체라고 합니다. 이 const 객체 는 멤버 변수들이 모두 상수화 됩니다.
위에서 상수형 메서드를 다루면서, "상수형 메서드의 상수화 방법은 this 포인터를 상수 지시 포인터로 바꾼다."고 했었습니다. 상수형 객체에서도 동일합니다.
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
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
#include <iostream>
using namespace std;
class Test
{
public:
Test(int num)
: nData(num)
{
}
~Test() { }
// 상수형 메서드 선언 및 정의
int GetData() const
{
return nData; // 멤버 변수의 값을 읽을 수 있지만, 쓸 수는 없음.
}
void SetData(int n)
{
nData = n;
}
// 상수형 메서드 선언 및 정의
void Print() const
{
cout << GetData() << endl; // 상수형 메서드에서는 오직 상수형 메서드만 호출 가능!
}
private:
int nData = 0;
};
int main()
{
const Test t(10); // 단, 생성자 초기화 리스트를 통한 변수 초기화는 가능!
t.SetData(20); // 상수형 객체는 오직 상수형 메서드만 호출 가능 Error!
t.Print(); // 상수형 객체는 오직 상수형 메서드만 호출 가능!
return 0;
}
error: ‘this’ argument to member function ‘SetData’ has type ‘const Test’, but function is not marked const
객체 자신인 this 포인터가 상수 지시 포인터이기 때문에 멤버 변수의 값을 변경하지 못합니다. 따라서 상수형 메서드만 호출이 가능합니다.
상수형 메서드혹은상수형 객체가 호출하는 함수는 상수 함수임이 보장되어야 하기 때문에 멤버 변수의 값을 변경하지 않더라도,const가 선언되지 않은 함수는 호출할 수 없습니다.
const선언을 해줌으로써 컴파일러에 해당 함수가값을 변경하지 않는 const 함수라는 것을 지시(보장) 합니다.
04. 상수형 메서드의 예외 사항
지금까지 간단하게 const 메서드 와 const 객체 에 대해 알아보았습니다. const 키워드 자체는 컴파일러로 하여금 값을 변경시키지 못하게 하는 것이지만, 프로그래밍에서 예외 사항은 꼭 존재합니다. 그때 사용할 수 있는게 바로 mutable 키워드 와 const_cast<> 형변환 연산자 입니다.
이 두가지 모두 상수화 된 대상에서 const 예약어가 지정된 멤버를 뽑아 값을 쓰거나 호출할 수 있습니다.
mutable 키워드
다음과 같이 mutable 로 선언한 멤버 변수의 값은 상수형 메서드에서 쓰기가 허용됩니다.
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
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
#include <iostream>
using namespace std;
class Test
{
public:
Test(int num)
: nData(num)
{
}
~Test() { }
// 상수형 메서드 선언 및 정의
int GetData() const
{
nData = 20; // mutable 로 선언된 멤버 변수는 쓸 수 있음.
return nData;
}
void SetData(int n)
{
nData = n;
}
// 상수형 메서드 선언 및 정의
void Print() const
{
cout << GetData() << endl; // 상수형 메서드에서는 오직 상수형 메서드만 호출 가능!
}
private:
mutable int nData = 0;
};
int main()
{
const Test t(10); // 생성자 초기화 리스트를 통한 변수 초기화는 가능!
t.Print(); // 상수형 객체는 오직 상수형 메서드만 호출 가능!
return 0;
}
[출력 결과]
20
위 코드에서 GetData() 함수가 상수형 메서드임에도 mutable로 선언된 멤버 변수의 값은 상수형 메서드에서도 쓰기가 허용됩니다.
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
28
29
30
31
32
33
34
35
36
class Test
{
public:
...
// 상수형 메서드 선언 및 정의
int GetData() const
{
return nData;
}
void SetData(int n)
{
nData = n;
}
// 상수형 메서드 선언 및 정의
void Print() const
{
cout << GetData() << endl; // 상수형 메서드에서는 오직 상수형 메서드만 호출 가능!
}
private:
mutable int nData = 0;
};
int main()
{
const Test t(10); // 생성자 초기화 리스트를 통한 변수 초기화는 가능!
// t.SetData(20); 상수형 객체는 오직 상수형 메서드만 호출 가능 Error!
t.nData = 20; // mutable 로 선언된 멤버 변수는 쓸 수 있음.
t.Print();
return 0;
}
[출력 결과]
20
상수형 메서드에서의 쓰기와 마찬가지로 상수형 객체에서도 mutable로 선언된 멤버 변수의 값에 쓰기가 가능합니다.
const_cast<> 형변환 연산자
또한, 상수형 참조인 경우 참조자를 통해 참조 원본에 접근하더라도 읽기만 허용될 뿐 쓰기는 불가능합니다. 그러나 가끔 억지로라도 쓰기를 해야하는 경우가 있는데, 이럴 때 const_cast<> 를 사용합니다. 하지만, 그렇다고 남발하는 것은 상수성을 깨트릴 수 있습니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include <iostream>
using namespace std;
// 상수형 참조의 nParam를 매개변수로 받음
void func(const int& nParam)
{
// 상수형 참조였으나 일반 참조로 형변환
int &nNewParam = const_cast<int &>(nParam);
// 쓰기 가능.
nNewParam = 20;
}
int main()
{
int nData = 10;
func(nData);
cout << nData << endl;
return 0;
}
[출력 결과]
20
위코드에서func() 함수의 매개변수 형식은 const int&로 정수 상수형 참조입니다. 이것을 const_cast<> 를 사용하여 상수형 참조 대상을 일반 참조로 변경할 수 있습니다.
const_cast<> 의 형태는 다음과 같습니다.
const_cast<새 형식>(대상)
05. 상수의 중요성
여기서부터 핵심이라고 할 수 있습니다. 바로 상수의 사용 이유인데요. 저번 포스팅의 해당 코드를 가져왔습니다.
다음 코드에서 오버로딩된 operator+() 함수를 보겠습니다.
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
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
// https://github.com/orion-gz/CPP-STL-Programming/blob/main/Chap01/Operator1.cpp
// 연산자 오버로딩
// 기본 타입이 아닌 클래스 타입, 즉 사용자 정의 타입에도 연산자를 사용할 수 있게 하는 문법.
// 연산자 오버로딩을 사용하면 컴파일러 내부에 정의되지 않은 타입의 연산이 가능하여 코드의 '직관성'과 '가독성'을 좋게 할 수 있음.
// 핵심은 클래스 타입의 객체에 연산자를 사용하면 컴파일러가 정의된 함수를 호출하는 데 있다.
#include <iostream>
using namespace std;
class Point
{
int x, y;
public:
Point(int _x = 0, int _y = 0)
: x(_x), y(_y)
{
}
void Print() const
{
cout << x << ',' << y << endl;
}
// 값을 반환해야 하므로 상수형 객체를 반환함 (const 선언으로 반환되는 값이 수정하는 것을 방지함)
// 함수 내에서 멤버 변수를 변경하지 않으므로 const 상수형 메서드 선언
const Point operator+(const Point& arg) const
{
Point pt;
pt.x = this->x + arg.x;
pt.y = this->y + arg.y;
return pt;
}
};
int main()
{
Point p1(2, 3), p2(5, 5);
Point p3;
p3 = p1 + p2; // 컴파일러가 p1.operator+(p2)로 해석해서 호출
p3.Print();
p3 = p1.operator+(p2); // 직접 호출
p3.Print();
return 0;
}
위 코드에서 바로 이 부분이 핵심입니다. 아래 코드를 보면 상수 메서드의 매개변수로 상수 참조를 받고, 반환 역시 상수로 반환합니다.
1
2
3
4
5
6
7
8
9
10
// 값을 반환해야 하므로 상수형 객체를 반환함 (const 선언으로 반환되는 값이 수정하는 것을 방지함)
// 함수 내에서 멤버 변수를 변경하지 않으므로 const 상수형 메서드 선언
const Point operator+(const Point& arg) const
{
Point pt;
pt.x = this->x + arg.x;
pt.y = this->y + arg.y;
return pt;
}
세가지의 const의 의미를 설명하면서 그 이유가 무엇인지에 대해 알아보겠습니다.
상수형 메서드 : const Point operator+(const Point& arg) const
위에서 우리는 상수형 메서드에 대해 배웠습니다. 값을 변경하면 안되는 상황에서 메서드에 const 선언을 하여 해당 클래스의 멤버 변수를 바꾸지 않겠다는 의미였었죠?
저번 글에서도 이야기 했다시피 operator+() 함수가 연산자 함수이기 때문에 절대 오류가 발생하면 안됩니다. 따라서, 클래스의 멤버 변수인 x, y에 영향을 주지 않기 위해 상수형 메서드로 멤버 변수를 상수화 한 것입니다.
함수의 매개변수 : const Point operator+(const Point& arg) const
매개변수를 상수형 참조로 받는 것은 Call by reference 로 복사의 오버헤드 없이 변수를 참조하고, 해당 변수를 함수 내에서 변경하지 않겠다는 의미입니다. 또한, 복사 생성자가 호출되지 않습니다.
또한, 일반적인 Call by value 로 매개변수를 인자로 넘겨주었을 때의 데이터 복사가 발생하지 않고, 매개변수는 넘겨받은 인자의 참조자가 되기에 메모리 낭비 역시 줄일 수 있습니다.
참조자의 특성 상 매개변수를 변경하게되면 원본 데이터까지 변경될 수 있기 때문에 const 키워드를 같이 사용하는 것입니다.
함수의 매개변수 형식이 클래스 형식이라면..
상수형 참조로 선언하는 것이 바람직합니다. 일단, 참조 형식으로 받은 매개변수는 객체를 복사 생성하지 않아 메모리 낭비를 줄일 수 있지만, 실인수로 기술한객체가 함수 호출때문에 값이 변경될 수 있기 때문입니다.
함수의 반환값 : const Point operator+(const Point& arg) const
상수 객체를 리턴하고 있습니다. 정확하게 이야기 하자면, 함수 내의 Point pt 라는 임시 객체를 상수화하여 리턴하고 있습니다. 위와 동일하게 반환하는 값이 수정되는 것을 방지하기 위함이 있습니다.
06. 정리
C/C++ 에서 const 란 마치 계단의 난간과도 같습니다. 만일 모든 건물의 모든 계단에 난간이 없다고 생각해본다면, 굉장히 불안정하게 걷다가 자칫 위험할 수 있습니다. 이럴 때 난간은 붙들고 의지할 수도 있을 뿐만 아니라 난간 밖으로 떨어지지 않도록 우리를 보호해 줍니다.
마찬가지로 const 키워드는 멤버의 값을 쓸 수 없도록 하거나 상수형 메서드가 아닌 멤버를 호출할 수 없게 함으로써 상수형 메서드를 안정적으로 사용할 수 있게 하는 일종의 조력자가 되는 것입니다. 최선을 다해 const를 사용하는 것이 좋습니다.
"정말 실력 있는 C++ 프로그래머는 const를 제대로 사용할 줄 안다."
"소스 코드에서 const 에약어 개수만 세어봐도 작성자의 수준을 가늠할 수 있다."
라는 말이 있을정도로 C++에서 const 사용은 매우 중요합니다.
자 그럼 지금까지 내용을 바탕으로 상수의 중요성에 대해 간단히 정리해 보겠습니다.
정리
코드의 안정성 및 실수 방지:const를 사용하면 값이나 객체가 변경되지 않도록 강제하므로, 실수로 값을 수정하는 경우를 방지할 수 있습니다.함수 매개변수: 함수 매개변수에const를 사용하면 해당 매개변수가 함수 내에서 변경되지 않음을 명시할 수 있습니다. 또한, 상수 객체 참조자를 인자로 받으면 데이터 복사가 일어나지 않고, 메모리 낭비를 줄일 수 있습니다.상수형 메서드:const멤버 함수를 사용하면 해당 클래스 내 함수가 멤버 변수를 변경하지 않음을 보장할 수 있습니다. 이는 객체의 상수성을 유지할 수 있도록 도와줍니다.함수 반환값: 함수가 상수로 반환하는 값을 변경할 수 없게 만들면, 반환된 값은 호출한 곳에서 변경될 위험이 없게 됩니다. 이를 통해코드의 안전성을 높일 수 있습니다.가독성 및 사용자 의도 표현:const를 사용하면 해당변수,객체,함수가읽기 전용임을 명시적으로 표현할 수 있습니다. 이로 인해변경하면 안된다는 의도역시 명확하게 전달할 수 있습니다.컴파일러 최적화:const를 사용하면 컴파일러가 더 많은 최적화를 수행할 수 있습니다.
const의 최적화에 대한 내용은 저도 확실하게 아는 내용이 아니라 관련 참고 자료만 남겨두도록 하겠습니다.
마무리 하며..
이번 챕터에서는 정말정말 중요한 const 키워드에 대해 알아보았습니다. 이번 장을 설명하면서 더 중요한 내용, 깊이 있는 내용을 꼼꼼하고 세세하게 다루어보고 싶었지만,, C++는 파고들면 파고들수록 내가 몰랐던 내용이 수두룩하게 나오는 정말,, 배우는 재미가 있는 언어입니다. 머리가 아프긴 해도 ‘C++ 좀 할줄 안다’ 하려면 지금의 수준으로는 많이 부족한듯 싶습니다. 이 내용 설명하면서 복사생성, 이동시맨틱 등에 대해 같이 부연설명드리고 싶었으나, 내용이 길어지기도 하고 아직 조금 정리가 안된 터라 다음에 다루어 보도록 하겠습니다.
잘 모르는 부분이나, 이해 안가는 부분, 또는 질문 있으시다면 남겨주시기 바랍니다. 아는 한에서 최대한 답변해드릴 수 있도록 노력하겠습니다!!
본문 내용에 잘못된 내용이나 오탈자가 있다면 댓글 부탁드립니다!!