공부/Unity

24.04.22

월러비 2024. 4. 22. 18:22

깊은 복사

  • 깊은 복사는 전체 복사로 생각하면 좋다.
  • 얕은 복사와 달리 객체가 가진 모든 멤버를 복사하는 것을 말한다.
  • 객체가 참조 타입의 멤버를 포함할 경우 참조값의 복사가 아닌 참조된 ‘객체 자체’가 복사되는 것을 말한다.
  • 깊은 복사는 새로이 동적할당을 받고, 원본의 데이터를 복사한다.
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);
}
  • 복사 생성자를 사용할때 ‘대입 연산자’를 정의하지 않으면 디폴트 대입 연산자가 생기고, ‘얕은 복사’를 한다.
  • 연산자 내에서 동적 할당을 하거나 깊은 복사가 필요하면 직접 정의를 해야한다.
    Character character("Player"); //문자열을 받은 생성자 호출
    Character character3;
    character3 = character; //얕은 복사로 delete할때 에러가 발생한다.
    
    복사 생성자의 경우
  • 대입 연산자 오버로딩의 경우
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 : 중괄호안에서는 변수의 값을 변경할 수 없다는 의미다.

복사 생성자

  • 한 객체의 내용을 다른 객체로 복사하여 생성된 생성자
  • 자신과 같은 타입의 객체를 인자로 받는다.
  • 복사 생성자가 정의되어 있지 않다면, 디폴트 복사 생성자가 생성된다.

복사 생성자 호출하는 방법

  1. 복사 생성자 : 자신의 클래스 타입으로 초기화된다. (같은 자료형의 객체로 초기화할 때 사용한다.) / 기본 소멸자의 호출만 나온다.
Character character2(character);
  1. 함수의 파라미터로 넘길때
SetCharacter(character);
  1. 복사생성자 : 리턴할때
Character SetCharacter(Character character)
{
	return character; //3. 복사생성자 : 리턴할때
}

가상화

  • 원래 가상화가 일어나면 ~~녹음
  • C에서 가상화가 가능한 조건 : 동적 할당이 되어야한다.
  • 가상화가 이뤄지면 부모 소멸자만 일어나니, 반드시 부모 소멸자에 virtual로 해서 자식 소멸자도 일어나게 해야한다. 녹음
    1. 동적 할당이어야 한다.
    2. ‘부모’에 가상 함수가 ‘1개 이상’ 있어야한다.
    3. 가상 소멸자를 만들어 줘야 한다.
  • C에서의 가상화 조건

가상 소멸자

순수 가상 함수

C에서의 추상

  • 순수 가상 함수 라는 개념을 쓴다.
    • 객체화할 수 없다.
    • 녹음 듣자
  • 추상 클래스 특징

함수포인터

  • C#은 함수포인터가 없어서 delegate를 썼다.
    • 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

'공부 > Unity' 카테고리의 다른 글

24.04.24  (8) 2024.04.25
24.04.23  (0) 2024.04.24
24.04.19  (0) 2024.04.22
24.04.18  (1) 2024.04.18
24.04.17  (1) 2024.04.17