카테고리 없음

[C ++ 11] Force Move 의미론

행복을전해요 2021. 2. 7. 03:39

당신은 값이 아니라 참조

m2

선언 하고 있습니다. 따라서 그것은 여전히 ​​초기화 된 것을 나타냅니다 . 당신은 이것을 원했습니다 :

m1

 

MyClass mc2 = std::move(mc);

라이브 예

두 번째 부분에 관해서는 다음과 같은 구성을 강제하는 방법이 없습니다.

MyClass mc2(mc); //Move, not copy
//-or-
MyClass mc2 = mc; //Move, not copy

이동. lvalue에서 이동하려면 (

mc

실제로 lvalue 임

std::move

) 명시 적으로 사용해야합니다 (또는 rvalue 로의 또 다른 캐스트).당신

있는 한 가지가 있지만 그것은 더러운 해킹이 될 것이고, 코드를 직관적이지 않게 만들고 버그의 훌륭한 소스가 될 것입니다. 이동을 수행하는 상수가 아닌 참조를 사용하는 복사 생성자 (및 복사 할당 연산자)의 오버로드를 추가 할 수 있습니다. 기본적으로

std::auto_ptr

정당하게 폐기되기 전에 사용했던 것과 같은 것 입니다. 그러나 예를 들어 코드 검토를 통과하지 못할 것입니다. 이동하려면

std::move

.


몇 가지 참고 사항 :

  • delete

    또는

    delete[]

    null 포인터를 호출 하는 것은 작동하지 않는 것이 보장되므로

    if

    소멸자에서 안전하게 삭제할 수 있습니다 .
  • 일반적으로 C ++ 코드

    std::copy

    대신 사용 하는 것이 바람직

    memcpy

    하며

    sizeof

    올바른 방법에 대해 걱정할 필요가 없습니다.

-------------------
복사 생성자와 할당 연산자를 삭제하면 이동 의미 체계를 강제 할 수 있습니다.

MyClass(const MyClass& src)= delete;
void operator=(const MyClass& src) = delete;

이 경우 제공된 이동 생성자 또는 이동 할당 연산자가 선택됩니다.-------------------

몇 가지 주석으로 수업을 약간 다시 작성하십시오.

그것을 살펴보면 놓친 몇 가지를 알 수 있습니다. 처럼:

  • MyClass(size_t c)확인하지 않습니다 c != 0.
  • void operator=(const MyClass& src)없는 delete[] data; (있는 경우) 재 할당하기 전에.

그리고 다른 작은 세부 사항. 컴파일러가 이것을 처리 할 수 ​​있기를 바랍니다.

class MyClass {
private:
    // initialize memebers directly
        int* data = nullptr;
            size_t count = 0;
            public:
                // default empty contructor
                    MyClass() = default;
                        // destructor
                            ~MyClass() {
                                    *this = nullptr; // use operator = (nullptr_t)
                                        }
                                            // allow nullptr construct
                                                MyClass(nullptr_t):MyClass() {}
                                                    // allow nullptr assignment (for clearing)
                                                        MyClass& operator = (nullptr_t) {
                                                                if(data) {
                                                                            delete[] data;
                                                                                        data = nullptr;
                                                                                                }
                                                                                                        count = 0;
                                                                                                                return *this;
                                                                                                                    }
                                                                                                                        // chain to default constructor, redundant in this case
                                                                                                                            MyClass(size_t c):MyClass() {
                                                                                                                                    // maybe size_t is 0?
                                                                                                                                            if(count = c) {
                                                                                                                                                        data = new int[count];
                                                                                                                                                                }
                                                                                                                                                                    }
                                                                                                                                                                        // chain to default constructor, redundant in this case
                                                                                                                                                                            MyClass(MyClass&& src):MyClass() {
                                                                                                                                                                                    *this = std::move(src); // forward to move assignment
                                                                                                                                                                                        }
                                                                                                                                                                                            MyClass& operator=(MyClass&& src) {
                                                                                                                                                                                                    // don't swap with self
                                                                                                                                                                                                            if(&src != this) {
                                                                                                                                                                                                                        // it's better to swap and let src destroy when it feels like it.
                                                                                                                                                                                                                                    // I always write move contructor and assignment to swap data.
                                                                                                                                                                                                                                                // it's gonna be destroyed anyway, or not...
                                                                                                                                                                                                                                                            std::swap(src.data, data);
                                                                                                                                                                                                                                                                        std::swap(src.count, count);
                                                                                                                                                                                                                                                                                }
                                                                                                                                                                                                                                                                                        return *this;
                                                                                                                                                                                                                                                                                            }
                                                                                                                                                                                                                                                                                                MyClass(const MyClass& src):MyClass() {
                                                                                                                                                                                                                                                                                                        *this = src; // forward to copy assignment
                                                                                                                                                                                                                                                                                                            }
                                                                                                                                                                                                                                                                                                                MyClass& operator = (const MyClass& src) {
                                                                                                                                                                                                                                                                                                                        // don't copy to self
                                                                                                                                                                                                                                                                                                                                if(&src != this) {
                                                                                                                                                                                                                                                                                                                                            // delete first
                                                                                                                                                                                                                                                                                                                                                        if(data) {
                                                                                                                                                                                                                                                                                                                                                                        delete[] data;
                                                                                                                                                                                                                                                                                                                                                                                        data = nullptr;
                                                                                                                                                                                                                                                                                                                                                                                                    }
                                                                                                                                                                                                                                                                                                                                                                                                    
                                                                                                                                                                                                                                                                                                                                                                                                                // now reallocate
                                                                                                                                                                                                                                                                                                                                                                                                                            if(count = src.count) {
                                                                                                                                                                                                                                                                                                                                                                                                                                            data = new int[count];
                                                                                                                                                                                                                                                                                                                                                                                                                                                            memcpy(data, src.data, sizeof(int)* count);
                                                                                                                                                                                                                                                                                                                                                                                                                                                                        }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        return *this;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                // easy way to use the object in a if(object) to test if it has content
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    explicit operator bool() const {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            return data && count;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    // same as above but made for if(!object) to test if empty
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        bool operator !() const {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                return !data || !count;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    public:
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        int* get_data() const {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                return data;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        size_t get_count() const {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                return count;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        // add more custom methods
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        };
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        

이제 이동하려면 다음을 수행하십시오.

MyClass object1; // default construct
MyClass object1(5); // construct with capacity
MyClass object2(object1); // copy constructor
MyClass object3(std::move(object1)); // move constructor
object2 = object1; // copy assignment
object3 = std::move(object1); // move constructor
std::swap(object2, object3); // swap the two
object2 = nullptr; // to empty it
if(object1); // bool cast



출처
https://stackoverflow.com/questions/22050218