깊은 복사
- 깊은 복사는 전체 복사로 생각하면 좋다.
- 얕은 복사와 달리 객체가 가진 모든 멤버를 복사하는 것을 말한다.
- 객체가 참조 타입의 멤버를 포함할 경우 참조값의 복사가 아닌 참조된 ‘객체 자체’가 복사되는 것을 말한다.
- 깊은 복사는 새로이 동적할당을 받고, 원본의 데이터를 복사한다.
class A
{
string a;
}
A ob = new A();
A obb = new A();
ob.a = "abc";
obb = ob; => 기본 대입 연산자
- 기본 대입 연산자 -> 스트링은 레퍼런스이니 어딘가 힙에 스트링 공간이 있고 여기에 abc가 들어가있다.
- 주소를 가지고 있는것이고, 주소가 복사되는 것이다.
- 두개의 변수가 주소를 참조하게 되는것이니 하나가 사라져도 스트링 주소공간의 값은 변하지 않는다.
암시적 멤버 메서드
- 기본 생성자
- 기본 소멸자
- 복사 생성자 : 객체가 복사 생성되어야할때
- 이동 생성자 : 기초 C++보고 정리해라
- 대입 연산자 : 기초 C++보고 정리해라
- 이동 대입 연산자 : 기초 C++보고 정리해라
얕은 복사
- 얕은 복사는 객체가 가진 멤버들의 값을 새로운 객체로 복사하는데 만약 개체가 참조타입의 멤버를 가지고 있다면 참조값만 복사가 된다.
- 얕은 복사의 경우 동적 할당을 받은 변수의 주소값을 공유한다.
- 참조로 받을 경우 주소값을 공유한다.
- 복사한 대상자가 바뀌면 복사한 객체도 같이 변한다.
- 얕은 복사는 의존적인 복사라고 생각하면 좋다.
Character character3;
character3 = character; //얕은 복사로 delete할때 에러가 발생한다.
대입 연산자
Character& operator = (const Character& character) //대입연산자 '='를 재정의했다. / 이건 녹화를 다시 한번 보자
{
if (this == &character) //같은 공간의 객체를 가리킨다면?
{
return *this;
}
if (name != nullptr) //널이 아니라는 의미는 할당이 되었다는 것이다.
{
delete[] name;
}
length = character.length;
name = new char[length];
for (int i = 0; i < length; i++)
{
name[i] = character.name[i];
}
printf("대입연산자 : %s\\n", name);
}
Dot dot1(1, 2);
Dot dot2 = dot1;
C 문자열 특징
- char* str = “abc”;의 포인터 변수를 생성한다.
- str안에 abc와 빈공간 하나 총 배개의 배열 공간이 생기고 그것의 주소를 참조하게 된다.
- 즉, 문자열을 저장하면 배열로 생성되는 것이다.
const
- ‘값을 바꿀수 없다’를 의미한다.
- charconst*로 선언하면 문자열을 넣을때 생성되는 ‘배열’의 값을 바꿀수 없는것을 의미한다.
- const* const string a = “” ⇒ 주소도 못바꾸고 문자열 배열의 값도 못바꾸는것을 의미한다.
const int const* const Number(const int const * const number) const {} //이것도 가능하다. / const int const* : 주소 자체를 못바꾸게 한다. / const Number : 주소에 접근해서 그 안의 값을 못바꾸게 한다. / ) const : 중괄호안에서는 변수의 값을 변경할 수 없다는 의미다.
복사 생성자
- 한 객체의 내용을 다른 객체로 복사하여 생성된 생성자
- 자신과 같은 타입의 객체를 인자로 받는다.
- 복사 생성자가 정의되어 있지 않다면, 디폴트 복사 생성자가 생성된다.
복사 생성자 호출하는 방법
- 복사 생성자 : 자신의 클래스 타입으로 초기화된다. (같은 자료형의 객체로 초기화할 때 사용한다.) / 기본 소멸자의 호출만 나온다.
Character character2(character);
- 함수의 파라미터로 넘길때
SetCharacter(character);
- 복사생성자 : 리턴할때
Character SetCharacter(Character character)
{
return character; //3. 복사생성자 : 리턴할때
}
가상화
- 원래 가상화가 일어나면 ~~녹음
- C에서 가상화가 가능한 조건 : 동적 할당이 되어야한다.
- 가상화가 이뤄지면 부모 소멸자만 일어나니, 반드시 부모 소멸자에 virtual로 해서 자식 소멸자도 일어나게 해야한다. 녹음
- 동적 할당이어야 한다.
- ‘부모’에 가상 함수가 ‘1개 이상’ 있어야한다.
- 가상 소멸자를 만들어 줘야 한다.
- C에서의 가상화 조건
가상 소멸자
순수 가상 함수
C에서의 추상
- 순수 가상 함수 라는 개념을 쓴다.
- 추상 클래스 특징
함수포인터
- C#은 함수포인터가 없어서 delegate를 썼다.
- delegate와 똑같은 기능이다.
- 델리게이트처럼 함수의 기능을 래핑({})해서 작성하는 것이다.
void Print() //파라미터 타입이 포인터의 타입이다. / void의 타입은 *func다.
{
printf("Print\\n");
}
void Print2(void (*func)())
{
printf("func 실행\\n");
func();
}
int Print3(int a, int b)
{
printf("Print3\\n");
return a + b;
}
int main()
{
void (*func)() = Print; //(*func)가 변수이자 리턴타입이다. / 기본실행 1
func();
Print2(Print); //기본실행 2
int (*func2)(int, int) = Print3; //실제 C#의 델리게이트도 이런식으로 변환이 된다.
return 0;
}
델리게이트
- delegate 자료형 이름 (파라미터);
- int (*func2)(int, int) = Print3; 와 같다.
함수포인터 - vector
함수포인터 - function