提问人:Vince 提问时间:8/26/2020 更新时间:8/26/2020 访问量:146
C++:移动赋值运算符和继承
c++ : move assignement operator and inheritance
问:
此代码编译并运行良好:
#include <iostream>
class Base
{
public:
Base(int value)
: clean_(true)
{
value_ = new int;
*value_ = value;
}
~Base()
{
if(clean_)
delete value_;
}
Base(Base&& other) noexcept
: value_{std::move(other.value_)},
clean_(true)
{
other.clean_=false;
}
Base& operator=(Base&& other) noexcept
{
value_ = std::move(other.value_);
other.clean_=false;
clean_=true;
}
void print()
{
std::cout << value_ << " : " << *value_ << std::endl;
}
int* value_;
bool clean_;
};
class A : public Base
{
public:
A(int v1, double v2) : Base(v1)
{
a_ = new double;
*a_ = v2;
}
A(A&& other) noexcept
: Base(std::forward<Base>(other)),
a_(std::move(other.a_))
{}
A& operator=(A&& other) noexcept
{
// should not the move assignment operator
// of Base be called instead ?
// If so: how ?
this->value_ = std::move(other.value_);
other.clean_=false;
this->clean_=true;
a_ = std::move(other.a_);
}
void print()
{
std::cout << this->value_ << " "
<< *(this->value_) << " "
<< a_ << " " << *a_ << std::endl;
}
double* a_;
bool clean_;
};
A create_a(int v1,double v2)
{
A a(v1,v2);
return a;
}
int main()
{
Base b1(20);
b1.print();
Base b2 = std::move(b1);
b2.print();
A a1(10,50.2);
a1.print();
A a2 = std::move(a1);
a2.print();
A a3 = create_a(1,2);
a3.print();
}
A 是 Base 的子类。
移动赋值运算符 A 的代码复制了 Base 的代码。
有没有办法避免这种代码复制?
答:
1赞
NathanOliver
8/26/2020
#1
更改为 和 to 后,您不再需要编写任何特殊成员函数,因为编译器提供的默认值 Just Work™int* value_;
int value_;
double* a_;
double a_;
如果确实需要动态内存分配,请使用 RAII 类型,如 、 、 等。取而代之的是,因为它们被设计为可以正确复制和/或移动。std::vector
std::unique_ptr
std::shared_ptr
评论
0赞
Vince
8/26/2020
对于这个特定的例子,这是有道理的,但这只是一些使问题清晰的最小代码。您如何调用基类的移动赋值运算符,考虑到这个最新的并不像这里举例的那样微不足道?
1赞
NathanOliver
8/26/2020
@Vince 诀窍是使用 RAII 类型。那么你什么都不用做,正确的行为就会提供给你。如果确实要调用基类移动赋值,请执行,这将调用基类的移动赋值运算符。Base::operator=(std::move(other));
0赞
Vince
8/26/2020
感谢您的回答,这奏效了!(我的原始代码是操作指向某些进程间共享内存的指针。
上一个:C++ 继承和赋值运算符
下一个:C++ 中运算符 = 的奇怪行为
评论
unique_ptr<int>
clean_
A
std::move
a_ = std::move(other.a_);
a_
std::move
r-value
other.a_
a_ = other.a_