我应该如何在菱形模式中调用父移动构造函数?
How should I call parent move constructor in diamond pattern?
考虑以下菱形多重继承:
class base;
class d1 : virtual public base;
class d2 : virtual public base
class d3 : public d1, public d2;
base
是一个只移动 class (有一个大的只移动缓冲区)。 d1
、d2
和 d3
也是如此。 d1
和 d2
的移动构造函数调用 base
的移动构造函数。
那么d3
的move构造函数应该怎么做呢?同时调用 d1 和 d2 的移动构造函数会导致崩溃(因为 base
的移动构造函数被调用了两次。
这里我有一个问题的最小可编译实例:
#include <iostream>
struct moveonly {
moveonly(): data(nullptr) {}
moveonly(const moveonly &) = delete;
moveonly(moveonly &&other) {
this->data = other.data;
other.data = nullptr;
}
~moveonly() {
if(data)
delete[] data;
}
char *data;
};
class base {
public:
base() = default;
base(const base &) = delete;
base(base &&other) : d(std::move(other.d)) { }
virtual ~base() = default;
int a;
int b;
moveonly d;
};
class d1 : virtual public base {
public:
d1() = default;
d1(const base &) = delete;
d1(d1 &&other) : base(std::move(other)) { }
int x;
int y;
};
class d2 : virtual public base {
public:
d2() = default;
d2(const base &) = delete;
d2(d2 &&other) : base(std::move(other)) { }
int r;
int s;
};
class d3 : public d1, public d2 {
public:
d3() = default;
d3(const base &) = delete;
// What should I do here?
d3(d3 &&other) : d1(std::move(other)), d2(std::move(other)) { }
int p;
int q;
};
int main()
{
d3 child;
child.d.data = new char[1024];
for(size_t i = 0; i < 1024; ++i)
child.d.data[i] = i * 2;
d3 other_child = std::move(child);
for(size_t i = 0; i < 1024; ++i) {
std::cerr << other_child.d.data[i] << ' ';
}
std::cerr << std::endl;
return 0;
}
与所有虚继承一样,虚基由最衍生对象初始化,因此:
d3(d3 &&other)
: base(std::move(other)), // <== *you* initialize the base
d1(std::move(other)),
d2(std::move(other)) {}
要求编译器提供实现有什么问题?
d3(d3 &&) = 默认值; // 我认为这是最好的方法,因为它的错误率较低。
如果你真的想,你可以把它写出来:
d3(d3 &&other): base(std::move(other)), d1(std::move(other)), d2(std::move(other))
{
}
考虑以下菱形多重继承:
class base;
class d1 : virtual public base;
class d2 : virtual public base
class d3 : public d1, public d2;
base
是一个只移动 class (有一个大的只移动缓冲区)。 d1
、d2
和 d3
也是如此。 d1
和 d2
的移动构造函数调用 base
的移动构造函数。
那么d3
的move构造函数应该怎么做呢?同时调用 d1 和 d2 的移动构造函数会导致崩溃(因为 base
的移动构造函数被调用了两次。
这里我有一个问题的最小可编译实例:
#include <iostream>
struct moveonly {
moveonly(): data(nullptr) {}
moveonly(const moveonly &) = delete;
moveonly(moveonly &&other) {
this->data = other.data;
other.data = nullptr;
}
~moveonly() {
if(data)
delete[] data;
}
char *data;
};
class base {
public:
base() = default;
base(const base &) = delete;
base(base &&other) : d(std::move(other.d)) { }
virtual ~base() = default;
int a;
int b;
moveonly d;
};
class d1 : virtual public base {
public:
d1() = default;
d1(const base &) = delete;
d1(d1 &&other) : base(std::move(other)) { }
int x;
int y;
};
class d2 : virtual public base {
public:
d2() = default;
d2(const base &) = delete;
d2(d2 &&other) : base(std::move(other)) { }
int r;
int s;
};
class d3 : public d1, public d2 {
public:
d3() = default;
d3(const base &) = delete;
// What should I do here?
d3(d3 &&other) : d1(std::move(other)), d2(std::move(other)) { }
int p;
int q;
};
int main()
{
d3 child;
child.d.data = new char[1024];
for(size_t i = 0; i < 1024; ++i)
child.d.data[i] = i * 2;
d3 other_child = std::move(child);
for(size_t i = 0; i < 1024; ++i) {
std::cerr << other_child.d.data[i] << ' ';
}
std::cerr << std::endl;
return 0;
}
与所有虚继承一样,虚基由最衍生对象初始化,因此:
d3(d3 &&other)
: base(std::move(other)), // <== *you* initialize the base
d1(std::move(other)),
d2(std::move(other)) {}
要求编译器提供实现有什么问题?
d3(d3 &&) = 默认值; // 我认为这是最好的方法,因为它的错误率较低。
如果你真的想,你可以把它写出来:
d3(d3 &&other): base(std::move(other)), d1(std::move(other)), d2(std::move(other)) {
}