下面是我遇到的两个类的缩小实现。
这是基类:
//header
class Script
{
public:
Script(const QString& path, int timeout=10000) :
mPath(path), mTimeout(timeout), script(new QProcess) {}
Script(Script&& s);
Script& operator=(Script&& s);
virtual ~Script();
protected:
QString mPath;
int mTimeout;
QProcess* script;
}
//source
Script::Script(Script&& s) :
mPath(s.mPath), mTimeout(s.Timeout), script(s.script)
{
s.script = nullptr;
}
Script& Script::operator=(Script&& s){
if(&s != this){
delete script;
script = s.script;
s.script = nullptr;
mPath = s.mPath;
mTimeout = s.mTimeout;
}
return *this;
}
Script::~Script() {
delete script;
script = nullptr;
}
从上面的代码片段中,我得出以下类:
//header
class ConfigurationScript : public Script
{
public:
ConfigurationScript(const QString& path);
ConfigurationScript(ConfigurationScript&& s);
ConfigurationScript& operator=(ConfigurationScript&& s);
}
//source
ConfigurationScript::ConfigurationScript(const QString& path) :
Script(path) {}
ConfigurationScript::ConfigurationScript(ConfigurationScript&& s) :
Script(std::move(s)) {}
ConfiguratonScript& ConfigurationScript::operator=(ConfigurationScript&& s) {
if(&s != this){
delete script;
script = s.script;
s.script = nullptr;
mPath = s.mPath;
mTimeout = s.mTimeout;
}
return *this;
}
将ConfigurationScript
的移动分配与其基类Script
的移动分配进行比较时,它包含重复的代码。您可以调用基类的赋值运算符来克服重复的代码吗?
例如这样有效吗?
ConfigurationScript& ConfigurationScript::operator=(ConfigurationScript&& s) {
if(&s != this){
Script::operator=(s);
}
return *this;
}
Script::operator=(s)
的返回类型为Script
,是否需要将其强制转换为ConfigurationScript
?
如果以上方法有效,我将看不到它的工作原理。否则,有没有办法避免代码重复?
答案 0 :(得分:2)
是的,这是有效的,而且您无需投放任何内容。
您甚至没有使用基本的op=
调用的结果,但是您知道它是一个Script&
引用当前对象。由于您已经有一个指向当前对象的ConfigurationScript&
,并且具有所需的类型(即*this
),因此无需执行其他操作。
实际上,这很自然,您可以让编译器为您完成:
#include <iostream>
#include <utility>
struct Base
{
Base& operator=(Base&& other)
{
std::cout << "YOLO!\n";
return *this;
}
};
struct Derived : Base
{
/*
// Don't need this
Derived& operator=(Derived&& other)
{
Base::operator=(std::move(other));
return *this;
}*/
/*
// Or even this (though you may need to introduce it
// if you have some other user-declared stuff)
Derived& operator=(Derived&& other) = default;
*/
};
int main()
{
Derived d1, d2;
d2 = std::move(d1);
}
// Output: YOLO!
但是我认为您可能是想Script::operator=(std::move(s))
才能获得真正的发展,而不是复制。