Point p1 {10,20};
Point p2 {30,40};
Point p3 = p1; **//대입 연산이 아닌 복사 생성이다.**
p3.ShowPosition();
Point p4;
p4 = p1; //대입 연산
p4.ShowPosition();
객체 1를 생성하며 ‘ = 객체 2 ‘ 가 올 때는 객체 2를 복사하여 객체 1을 만들겠다는 의미, 즉 복사 생성자
이미 만들어진 객체에 ‘ = ’ 가 올 때 대입 연산자가 호출 됨
Type& operator=(const Type& rhs);참조형으로 반환하여 추가적인 복사 연산을 하지 않도록 함
사용 예
Point& operator=(const Point& rhs)
p4 = p1;//대입 연산을 할 경우 아래의 함수가 호출 됨
p4.operator=(p1);
Point& operator=(const Point& rhs)**//없으면 컴파일러가 자동 구현해줌**
{
//예외처리하는 이유?, 멤버 변수가 포인터라면? -> 얕은 복사가 되기 때문에
if ( this == &rhs)
return *this;
xpos = rhs.xpos;
ypos = rhs.ypos;
return *this;
}
여기서 if로 예외처리 하는 이유는 표면적으로 봤을 때 같은 객체를 대입하는 것을 막기위해, 나머지 하나는 얕은복사 문제가 생길 수 있기 때문에 예외처리를 한 것이다.
#include <iostream>
class Array {
private:
int* ptr;
int size;
public:
Array(int val, int size)
:size{ size }
{
ptr = new int[size];//배열 동적생성
for (int i = 0; i < size; i++)
{
ptr[i] = val + i;
}
}
int GetSize() const
{
return size;
}
int GetValue(int index) const
{
if (index < size && index >= 0)//index 범위 안에 있다면
return ptr[index];
else
{
std::cout << "Out of Range!!" << std::endl;
}
}
~Array()
{
delete[] ptr;
}
};
int main()
{
Array a1{ 5,10 };
Array a2{ 3,5 };
a2 = a1; // 대입 연산자 자동 생성, 의도대로 동작하는지 모름
// ERROR 발생함
std::cout << a2.GetValue(0) << std::endl;
}
멤버 변수에 포인터가 있는 것을 생각해보면 a2의 멤버 변수의 값에 a1의 변수의 값을 복사해서 할당하면 a1.ptr와 a2.ptr이 같은 공간을 가리키게 된다. 즉, 이는 얕은 복사 문제가 발생하여 ‘이중 해제’ 문제가 발생하게 된다는 의미이다.
#include <iostream>
class Array {
private:
int* ptr;
int size;
public:
Array(int val, int size)
:size{ size }
{
ptr = new int[size];//배열 동적생성
for (int i = 0; i < size; i++)
{
ptr[i] = val + i;
}
}
int GetSize() const
{
return size;
}
int GetValue(int index) const
{
if (index < size && index >= 0)//index 범위 안에 있다면
return ptr[index];
else
{
std::cout << "Out of Range!!" << std::endl;
}
}
Array& operator=(const Array& rhs)//대입 연산자
{
if (this == &rhs)//동일 객체 대입 방지
return *this;//객체 반환
delete[] ptr;//메모리 누수 방지
size = rhs.size;
ptr = new int[size];
for (int i = 0; i < size; i++)
{
ptr[i] = rhs.ptr[i];
}
}
~Array()
{
delete[] ptr;
}
};
int main()
{
Array a1{ 5,10 };
Array a2{ 3,5 };
a2 = a1;
std::cout << a2.GetValue(0) << std::endl;
}
대입 연산자에서 얕은 복사를 피하기 위해서 새로운 공간을 할당해서 해당 공간안에 직접 a1의 값들을 복사 해줬다.
이때 a2가 이미 가리키고 있던 객체를 해제시켜 메모리 누수가 발생하지 않도록 한다.
대입 연산자는 “return *this;”를 해야한다.
이해가 가지 않아서 공부해봄.
Point& operator=(const Point& rhs)**//없으면 컴파일러가 자동 구현해줌**
{
if ( this == &rhs)
return *this;
xpos = rhs.xpos;
ypos = rhs.ypos;
return *this;
}
내가 생각한건 *this는 객체 그 자체를 말하는 것인데 어떻게 함수의 반환형이 Point로 될 수 있지?’ 였다.
(https://hwan-shell.tistory.com/38 해당 블로그를 참조해서 공부하였다)