C++ std::move

2021. 3. 24. 10:45·C++/Library

std::move

  • <utility> 라이브러리

  • 인자로 들어온 값을 R-value로 리턴해준다.


예제

  • std::move를 사용하지 않은 예제

    main.cpp

    #include <iostream>
    #include "Resource.h"
    #include "AutoPtr.h"
    using namespace std;
    
    int            main()
    {
      AutoPtr<Resource> res1(new Resource(10000000));
    
      cout << res1.ptr_ << endl;
    
      AutoPtr<Resource> res2 = res1;
    
      cout << res1.ptr_ << endl;
      cout << res2.ptr_ << endl;
    }
    
    /* stdout stderr
    Resource length constructed
    AutoPtr default constructor
    0158E360
    AutoPtr copy constructor
    Resource default constructed
    Resource copy assignment
    0158E360
    0158E408
    AutoPtr destructor
    Resource destoryed
    AutoPtr destructor
    Resource destoryed
    */

    Resource.h

    #pragma once
    
    #include <iostream>
    
    class Resource
    {
    public:
      int    *data_ = nullptr;
      unsigned length_ = 0;
    
      Resource()
      {
        std::cout << "Resource default constructed\n";
      }
    
      Resource(unsigned length)
      {
        std::cout << "Resource length constructed\n";
        init(length);
      }
    
      Resource(const Resource& res)
      {
        std::cout << "Resource copy constructed\n";
        init(res.length_);
        for (unsigned i = 0; i < length_; ++i)
          data_[i] = res.data_[i];
      }
    
      ~Resource()
      {
        std::cout << "Resource destoryed\n";
    
        if (data_ != nullptr) delete[] data_;
      }
    
      void    init(unsigned length)
      {
        data_ = new int[length];
        length_ = length;
      }
    
      Resource& operator = (Resource& res)
      {
        std::cout << "Resource copy assignment\n";
        if (&res == this) return *this;
    
        if (data_ != nullptr) delete[] data_;
        init(res.length_);
        for (unsigned i = 0; i < length_; ++i)
          data_[i] = res.data_[i];
        return *this;
      }
    
      void print()
      {
        for (unsigned i = 0; i < length_; ++i)
          std::cout << data_[i] << ' ';
        std::cout << std::endl;
      }
    };

    AutoPtr.h

    #pragma once
    
    #include <iostream>
    
    template<class T>
    class AutoPtr
    {
    public:
      T* ptr_;
    
      AutoPtr(T *ptr = nullptr)
        : ptr_(ptr)
      {
        std::cout << "AutoPtr default constructor\n";
      }
    
      AutoPtr(const AutoPtr& a)
        : ptr_(a.ptr_)
      {
        std::cout << "AutoPtr copy constructor\n";
        ptr_ = new T;
        *ptr_ = *a.ptr_;
      }
    
      AutoPtr(AutoPtr&& a)
        : ptr_(a.ptr_)
      {
        std::cout << "AutoPtr move constructor\n";
        a.ptr_ = nullptr;
      }
    
      ~AutoPtr()
      {
        std::cout << "AutoPtr destructor\n";
        if (ptr_ != nullptr) delete ptr_;
      }
    
      AutoPtr& operator = (const AutoPtr& a)
      {
        std::cout << "AutoPtr copy assignment\n";
        if (&a == this)
          return *this;
    
        if (ptr_ != nullptr) delete ptr_;
    
        ptr_ = new T;
        *ptr_ = *a.ptr_;
        return *this; 
      }
    
      AutoPtr& operator = (AutoPtr&& a)
      {
        std::cout << "AutoPtr move assignment\n";
    
        if (&a == this)
          return *this;
    
        if (ptr_ != nullptr) delete ptr_;
    
        ptr_ = a.ptr_;
        a.ptr_ = nullptr;
    
        return *this;
      }
    };

  • 위의 코드에서 main.cpp에 <utility> 라이브러리를 include 하고, std::move를 사용하면 다음과 같다.

    main.cpp

    #include <iostream>
    #include <utility>
    #include "Resource.h"
    #include "AutoPtr.h"
    using namespace std;
    
    int            main()
    {
      AutoPtr<Resource> res1(new Resource(10000000));
    
      cout << res1.ptr_ << endl;
    
      AutoPtr<Resource> res2 = std::move(res1);
    
      cout << res1.ptr_ << endl;
      cout << res2.ptr_ << endl;
    }
    
    /* stdout stderr
    Resource length constructed
    AutoPtr default constructor
    00CADF50
    AutoPtr move constructor
    00000000
    00CADF50
    AutoPtr destructor
    Resource destoryed
    AutoPtr destructor
    */

Swap 예제

main.cpp

  #include <iostream>
  #include <utility>
  #include "Resource.h"
  #include "AutoPtr.h"
  using namespace std;

  template<typename T>
  void        MySwap(T& a, T& b)
  {
    T tmp{ std::move(a) };
    a = std::move(b);
    b = std::move(tmp);
  }

  int            main()
  {
    AutoPtr<Resource> res1(new Resource(3));
    res1->setAll(3);

    AutoPtr<Resource> res2(new Resource(5));
    res2->setAll(5);

    res1->print();
    res2->print();

    MySwap(res1, res2);

    res1->print();
    res2->print();
  }

  /* stdout stderr
  Resource length constructed
  AutoPtr default constructor
  Resource length constructed
  AutoPtr default constructor
  3 3 3
  5 5 5 5 5
  AutoPtr move constructor
  AutoPtr move assignment
  AutoPtr move assignment
  AutoPtr destructor
  5 5 5 5 5
  3 3 3
  AutoPtr destructor
  Resource destoryed
  AutoPtr destructor
  Resource destoryed
  */

Resource.h

  #pragma once

  #include <iostream>

  class Resource
  {
  public:
    int    *data_ = nullptr;
    unsigned length_ = 0;

    Resource()
    {
      std::cout << "Resource default constructed\n";
    }

    Resource(unsigned length)
    {
      std::cout << "Resource length constructed\n";
      init(length);
    }

    Resource(const Resource& res)
    {
      std::cout << "Resource copy constructed\n";
      init(res.length_);
      for (unsigned i = 0; i < length_; ++i)
        data_[i] = res.data_[i];
    }

    ~Resource()
    {
      std::cout << "Resource destoryed\n";

      if (data_ != nullptr) delete[] data_;
    }

    void    init(unsigned length)
    {
      data_ = new int[length];
      length_ = length;
    }

    Resource& operator = (Resource& res)
    {
      std::cout << "Resource copy assignment\n";
      if (&res == this) return *this;

      if (data_ != nullptr) delete[] data_;
      init(res.length_);
      for (unsigned i = 0; i < length_; ++i)
        data_[i] = res.data_[i];
      return *this;
    }

    void    print()
    {
      for (unsigned i = 0; i < length_; ++i)
        std::cout << data_[i] << ' ';
      std::cout << std::endl;
    }

    void    setAll(const int& v)
    {
      for (unsigned i = 0; i < length_; ++i)
        data_[i] = v;
    }
  };

AutoPtr.h

  #pragma once

  #include <iostream>

  template<class T>
  class AutoPtr
  {
  public:
    T* ptr_;

    AutoPtr(T *ptr = nullptr)
      : ptr_(ptr)
    {
      std::cout << "AutoPtr default constructor\n";
    }

    AutoPtr(const AutoPtr& a)
      : ptr_(a.ptr_)
    {
      std::cout << "AutoPtr copy constructor\n";
      ptr_ = new T;
      *ptr_ = *a.ptr_;
    }

    AutoPtr(AutoPtr&& a)
      : ptr_(a.ptr_)
    {
      std::cout << "AutoPtr move constructor\n";
      a.ptr_ = nullptr;
    }

    ~AutoPtr()
    {
      std::cout << "AutoPtr destructor\n";
      if (ptr_ != nullptr) delete ptr_;
    }

    AutoPtr& operator = (const AutoPtr& a)
    {
      std::cout << "AutoPtr copy assignment\n";
      if (&a == this)
        return *this;

      if (ptr_ != nullptr) delete ptr_;

      ptr_ = new T;
      *ptr_ = *a.ptr_;
      return *this; 
    }

    AutoPtr& operator = (AutoPtr&& a)
    {
      std::cout << "AutoPtr move assignment\n";

      if (&a == this)
        return *this;

      if (ptr_ != nullptr) delete ptr_;

      ptr_ = a.ptr_;
      a.ptr_ = nullptr;

      return *this;
    }

      T* operator->() const { return ptr_; }
  };

대부분의 라이브러리는 R-value에 대해서도 정의가 되어있다.

  #include <iostream>
  #include <utility>
  #include <vector>
  using namespace std;

  int            main()
  {
    vector<string> v;
    string str = "Hello";

    v.push_back(str);

    cout << str << endl;
    cout << v[0] << endl;

    v.push_back(std::move(str));

    cout << str << endl;
    cout << v[0] << ' ' << v[1] << endl;
  }

  /* stdout stderr
  Hello
  Hello

  Hello Hello
  */
저작자표시 (새창열림)

'C++ > Library' 카테고리의 다른 글

C++ shared_ptr  (0) 2021.03.24
C++ unique_ptr  (0) 2021.03.24
C++ 출력 스트림 끊기  (0) 2021.03.24
C++ std::exception  (0) 2021.03.22
C++ reference_wrapper  (0) 2021.03.21
'C++/Library' 카테고리의 다른 글
  • C++ shared_ptr
  • C++ unique_ptr
  • C++ 출력 스트림 끊기
  • C++ std::exception
Caniro
Caniro
  • Caniro
    Minimalism
    Caniro
  • 전체
    오늘
    어제
    • 분류 전체보기 (317)
      • Algorithm (13)
        • 알기 쉬운 알고리즘 (10)
        • Search (1)
        • Sort (2)
      • Arduino (0)
      • C++ (185)
        • Class (46)
        • Exception (6)
        • Library (51)
        • Overloading (10)
        • SmartPointer (5)
        • Syntax (33)
        • TBC++ (23)
        • Templates (9)
        • VisualStudio (2)
      • Embedded (1)
      • Git (4)
      • Java (5)
      • Linux (16)
        • Error (1)
        • Linux Structure (11)
      • MacOS (7)
      • OS (1)
        • Concurrency (1)
      • Python (21)
        • Class (1)
        • Function (2)
        • Syntax (17)
      • Raspberrypi (9)
      • Review (1)
      • Utility (12)
        • VSCode (5)
        • VirtualBox (3)
      • Web (8)
        • Nginx (1)
        • React (3)
        • Django (1)
      • Windows (20)
        • Registry (3)
        • WSL (1)
        • DeviceDriver (6)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    시스템 복구
    로지텍 마우스 제스처
    윈도우
    제외
    그림판
    스프링 프레임워크 핵심 기술
    windows
    윈도우 명령어
    dism
    logi options
    SFC
    MacOS
    vscode
    mspaint
    unix
    Windows 11
    spring
    SunOS 5.1
    스프링
    Workspace
    알림
    EXCLUDE
    Solaris 10
    백기선
    java
    맥북 카카오톡 알림 안뜸
    KakaoTalk
    citrix workspace
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
Caniro
C++ std::move
상단으로

티스토리툴바