복사 생성자
- 어떤 객체를 복사하여 똑같은 타입의 객체를 생성할 때 복사 생성자가 호출
얕은 복사
- 변수가 가리키는 실제 데이터가 아닌 단지 메모리 주소만을 복사
깊은 복사
- 변수가 관리하는 리소스 자체를 복사(새롭게 메모리를 할당)
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <string>
class MyString {
public:
MyString(const char* n);
MyString(const MyString& other);
~MyString();
void SetString(const char* n);
const char* GetString() const;
int GetLength() const;
private:
void Release();
char* data;
int length;
};
MyString::MyString(const char* n) : data(nullptr), length(0) {
SetString(n);
printf("MyString::MyString(const char '%s')\n", n);
}
//복사 생성자
MyString::MyString(const MyString& other) : data(nullptr), length(0) {
SetString(other.GetString());
printf("MyString::MyString(const MyString& '%s')\n", data);
}
//소멸자
MyString::~MyString() {
printf("MyString::MySTring('%s') 소멸자 호출\n", data);
Release(); //할당받은 메모리 삭제
}
void MyString::SetString(const char* n) {
//인수의 문자열이 NULL인지 확인한다.
if (nullptr == n) {
std::cout << "nullptr" << std::endl;
return;
}
int mLength = strlen(n);
if (0 == mLength) {
std::cout << "" << std::endl;
return;
}
data = new char[mLength + 1];
std::strcpy(data, n);
length = mLength;
}
void MyString::Release() {
if (data != nullptr) {
delete[] data;
data = nullptr;
length = 0;
}
}
const char* MyString::GetString() const { return data; }
int MyString::GetLength() const { return length; }
void display(MyString other) { std::cout << other.GetString() << std::endl; }
int main() {
MyString s1("Hello World"), s2 = "복사 생성자";
display(s1); //복사 생성자 호출
s2 = s1; //복사 대입 연산자 호출
display(s2);
return 0;
}
디폴트 복사 생성자
- 얕은 복사 수행, 어떤 멤버 변수의 값과 주소가 모두 같음
복사받은 객체가 삭제되고 동적 할당된 메모리도 해제되면, 복사된 객체가 해당 주소에 접근하면 런타임 오류 발생
함수 중복
- 동일한 이름의 함수가 공존
- 다형성
- C 언어에서는 불가능
- function overloading
- 함수 중복이 가능한 범위
- 보통 함수들 사이
- 클래스의 멤버 함수들 사이
- 상속 관계에 있는 기본 클래스와 파생 클래스의 멤버 함수들 사이
함수 중복 성공 조건
- 중복된 함수들의 이름 동일
- 중복된 함수들의 매개 변수 타입이 다르거나 개수가 달라야 함
- 리턴 타입은 함수 중복과 무관
함수 중복 성공 사례
함수 중복 실패사례
리턴 타입이 다르다고 함수 중복이 성공하지 않음
함수 중복의 편리함
동일한 이름을 사용하면 함수 이름을 구분하여 기억할 필요 없고, 함수 호출을 잘못하는 실수를 줄일 수 있음
#예제 1번
#include <iostream>
using namespace std;
int big(int a, int b) { // a와 b 중 큰 수 리턴
if(a>b) return a;
else return b;
}
int big(int a[], int size) { // 배열 a[]에서 가장 큰 수 리턴
int res = a[0];
for(int i=1; i<size; i++)
if(res < a[i]) res = a[i];
return res;
}
int main() {
int array[5] = {1, 9, -2, 8, 6};
cout << big(2,3) << endl;
cout << big(array, 5) << endl;
}
생성자 함수 중복
- 생성자 함수 중복 목적
- 객체 생성시, 매개 변수를 통해 다양한 형태의 초깃값 전달
소멸자 함수 중복 불가
- 소멸자는 매개 변수를 가지지 않음
- 한 클래스 내에서 소멸자는 오직 하나만 존재
디폴트 매개 변수
- 기본값이 제공된 함수 매개 변수
사용자가 이 매개 변수의 값을 제공하지 않으면 기본값 사용
#include <iostream>
int Adder(int num1 = 1, int num2 = 2); // 디폴트 값은 함수 선언에서
int main(void)
{
std::cout << Adder() << std::endl; // Adder(1,2)
std::cout << Adder(5) << std::endl; // Adder(5,2)
std::cout << Adder(3, 5) << std::endl; // Adder(3,5)
system("pause"); // VC++ 에서만 필요
return 0;
}
int Adder(int num1, int num2)
{
return num1 + num2;
}
Default 값이 있으면 반복되는 매개변수를 빼기 때문에 함수를 좀 더 편리하게 사용할 수 있음
'개발 > C++' 카테고리의 다른 글
[C++] 상속 (0) | 2022.11.27 |
---|---|
[C++] Static (0) | 2022.11.20 |
[C++] 객체 치환 / 참조에 의한 호출 / 벡터 (0) | 2022.11.04 |
[C++ 10.18 7주차 수업] (0) | 2022.10.18 |
[C++] 템플릿 (0) | 2022.06.28 |