copy, move constructor

김대익·2022년 3월 3일

rule of three/five/zero란
멤버 변수로 raw pointer(예를 들면 char * mPtr)를 활용해 리소스를 관리하게되면
개발자가 직접

  • constructor
  • destructor
  • copy / move constructor
  • copy / move assignment
    함수를 구현해줘야한다
    을 모두 구현해야한다.

먼저 객체를 만들어보면

#include <iostream>
#include <string>
using namespace std;
class Cat {
public:
	Cat(string name, int age):mName{(move(name))}, mAge(age){};
    void print() {
    	cout << mName << " " << mAge << endl;
    }
private:
	string mName;
    int mAge;
    char * 
}

int main() {
	Cat kitty{"kitty", 1};
    Cat nabi;
    return 0;
}	

를 컴파일 할 경우 nabi객체를 만드는데 컴파일 에러가 생기는데

생성자에서 Cat(string name, int age)처럼 2개의 인수를 받는 생성자를 선언했기 때문에 인수를 받지않는 생성자를 disabled시켰기 때문이다.

따라서 Cat()=default;라고 알려주면 컴파일러가 자동적으로 만들어주는 default constructor를 사용해서 구현이 된다.

#include <iostream>
#include <string>
using namespace std;
class Cat {
public:
	Cat()=default;
	Cat(string name, int age):mName{(move(name))}, mAge(age){} {
    	cout << "constructor" << endl;
    }
    void print() {
    	cout << mName << " " << mAge << endl;
    }
    ~Cat() {
    	cout << "destructor" << endl;
    }
private:
	string mName;
    int mAge;
    char * mPtr
}

int main() {
	Cat kitty{"kitty", 1};
    Cat nabi;
    return 0;
}	

char * mPtr처럼 포인터를 이용해 리소스를 관리한다면
~Cat() destructor부분에서 delete mPtr;를 통해 해제해주어야한다.


copy constructor는 기존의 object를 똑같이 copy해서 새로운 object를 만드는 메서드이다.

#include <iostream>
#include <string>
using namespace std;
class Cat {
public:
	Cat()=default;
	Cat(string name, int age):mName{(move(name))}, mAge(age){} {
   	cout << "constructor" << endl;
   }
   Cat(const Cat& other):mName{other.mName}, mAge{other.mAge} {
   	cout << "copy constructor" << endl;
   }
   void print() {
   	cout << mName << " " << mAge << endl;
   }
   ~Cat() {
   	cout << "destructor" << endl;
   }
private:
	string mName;
   int mAge;
   char * mPtr
}

int main() {
   Cat kitty{"kitty", 1};
   Cat kitty2{kitty};
   Cat kitty3 = kitty;
   return 0;
}	

Cat kitty3 = kitty;에서 "="때문에 assignment가 개입될 거라 생각할 수 있지만
새로운 object가 만들어지는 과정이라 copy constructor가 호출된다.


코드를 실행해보면 먼저 kitty constructor가 생긴 뒤 copy constructor들이 실행되는 것을 알 수 있다.


move constructor

기존 object를 복사하는 copy constructor와 달리
move constructor는 기존 object의 ownership을 뺏어오는 방식이다

R value reference를 만들어서

Cat(Cat &&other):mName{std::move(other.mName)}, mAge{other.mAge}

0개의 댓글