당신은 값이 아니라 참조
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
null 포인터를 호출 하는 것은 작동하지 않는 것이 보장되므로delete[]
소멸자에서 안전하게 삭제할 수 있습니다 .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