C++의 이동 생성자

Jinku Hu 2023년10월12일
C++의 이동 생성자

이 기사에서는 C++에서 이동 생성자를 사용하는 방법을 소개합니다.

Move 생성자를 사용하여 C++의 클래스에 대한 효율적인 복사 제어 제공

클래스의 복사 제어는 클래스 객체가 복사, 이동, 할당 또는 소멸 될 때 발생하는 일을 지정하는 데 필요한 핵심 기능을 정의합니다. 이러한 함수는 복사 생성자 및 이동 생성자 함수와 같은 특수 C++ 명명법을 사용하여 객체가 동일한 유형의 다른 객체로 초기화되는 방법을 정의합니다. 복사 할당 및 이동 할당 기능은 객체가 동일한 유형의 객체에 할당되는 방법을 정의합니다. Destructor는 객체가 범위를 벗어날 때 실행되는 루틴을 처리합니다. 이러한 함수 중 일부는 사용자가 정의 할 가능성이 가장 높지만 그렇지 않은 경우 컴파일러 자체가 기본 프로토 타입을 만듭니다.

클래스 객체가 동적 메모리를 관리하고 데이터가 상당히 큰 경우 복사 작업이 다소 컴퓨팅 집약적 일 수 있습니다. 성능에 영향을 미치는 상당한 자원을 사용할 수 있습니다. 따라서 그들은 종종 이동 생성자를 사용하여 동적 데이터를 새 메모리 위치에 복사하지 않고 재 할당합니다. 이전 개체의 포인터를 새로 초기화되거나 할당 된 개체의 해당 멤버에 할당하여 수행됩니다. 다음 예제에는 이동 생성자가 포함되어 있지 않으며 기본 생성자에 위임하는 복사 생성자가 여러 번 호출됩니다.

#include <iostream>
#include <vector>

using std::cin;
using std::cout;
using std::endl;
using std::vector;

class MyClass {
 private:
  int* data;

 public:
  explicit MyClass(int d) {
    data = new int;
    *data = d;
    cout << "Constructor 1 is called" << endl;
  };

  MyClass(const MyClass& source) : MyClass(*source.data) {
    cout << "Copy Constructor is called " << endl;
  }

  int getData() const { return *data; }

  ~MyClass() {
    delete data;
    cout << "Destructor is called" << endl;
  }
};

void printVec(const vector<MyClass>& vec) {
  for (const auto& i : vec) {
    cout << i.getData() << " ";
  }
  cout << endl;
}

int main() {
  vector<MyClass> vec;

  vec.push_back(MyClass(10));
  vec.push_back(MyClass(11));
  printVec(vec);
  cout << "------------------" << endl;

  return EXIT_SUCCESS;
}

출력:

Constructor 1 is called
Constructor 1 is called
Copy Constructor is called
Destructor is called
Constructor 1 is called
Constructor 1 is called
Copy Constructor is called
Constructor 1 is called
Copy Constructor is called
Destructor is called
Destructor is called
10 11
------------------
Destructor is called
Destructor is called

일반적으로 r- 값 참조를 첫 번째 인수 (&&표기법으로 표시)로 가져야하는 이동 생성자를 정의하면MyClass유형의 새 요소가 추가됨에 따라 벡터 초기화가 더 효율적이됩니다. 이동 생성자는 새 메모리를 할당하지 않고 전달 된 객체가 보유한 위치를 차지하므로 이전 객체의 멤버에nullptr를 할당해야합니다. 그렇지 않으면 소멸자는 동일한 메모리 위치를 두 번 해제하여 런타임 오류를 발생시킵니다.

#include <iostream>
#include <vector>

using std::cin;
using std::cout;
using std::endl;
using std::vector;

class MyClass {
 private:
  int* data;

 public:
  explicit MyClass(int d) {
    data = new int;
    *data = d;
    cout << "Constructor 1 is called" << endl;
  };

  MyClass(const MyClass& source) : MyClass(*source.data) {
    cout << "Copy Constructor is called " << endl;
  }

  MyClass(MyClass&& source) noexcept : data(source.data) {
    source.data = nullptr;
    cout << "Move Constructor is called" << endl;
  }

  int getData() const { return *data; }

  ~MyClass() {
    delete data;
    cout << "Destructor is called" << endl;
  }
};

void printVec(const vector<MyClass>& vec) {
  for (const auto& i : vec) {
    cout << i.getData() << " ";
  }
  cout << endl;
}

int main() {
  vector<MyClass> vec;

  vec.push_back(MyClass(10));
  vec.push_back(MyClass(11));
  printVec(vec);
  cout << "------------------" << endl;

  return EXIT_SUCCESS;
}

출력:

Constructor 1 is called
Move Constructor is called
Destructor is called
Constructor 1 is called
Move Constructor is called
Move Constructor is called
Destructor is called
Destructor is called
10 11
------------------
Destructor is called
Destructor is called
작가: Jinku Hu
Jinku Hu avatar Jinku Hu avatar

Founder of DelftStack.com. Jinku has worked in the robotics and automotive industries for over 8 years. He sharpened his coding skills when he needed to do the automatic testing, data collection from remote servers and report creation from the endurance test. He is from an electrical/electronics engineering background but has expanded his interest to embedded electronics, embedded programming and front-/back-end programming.

LinkedIn Facebook

관련 문장 - C++ Class