"Inherit"移动操作,而无需访问基类成员变量
"Inherit" move operations without access to base-class member variables
作为右值引用和移动语义的新手,我试图从std::vector
派生一个简单的模板类(我保证我会小心缺少虚拟析构函数)。要"继承"move构造函数,我只需调用基类的对应类和std::move
,
template <typename T>
class Vec: public std::vector<T> {
public:
...
//move ctors
Vec(Vec&& v): std::vector<T>(v) { //move extra members with std::move }
explicit Vec(std::vector<T>&& v): std::vector<T>(v) { //same as above }
...
};
根据我对c++的理解,似乎是可信的。然而,我对移动赋值操作符
的方法信心不足。 //assignment
Vec& operator=(const Vec& v) {
std::vector<T>::operator=(v);
if (&v != this)
//copy extra members
return *this;
}
//move assignment
Vec& operator=(Vec&& v) {
std::vector<T>::operator=(v);
//move extra members with std::move
return *this;
}
这是一个万无一失的方法来实现我想要的吗?就良好实践而言,是否有更好的替代方案?
这似乎是值得信赖的…
似乎值得信赖。但事实并非如此。你看,这个:
Vec(Vec&& v)
是移动构造函数。所以它会带一个右值被调用。但一旦我们进入这里,v
是左值!经验法则:如果它有名字,它就是左值。所以这部分:
: std::vector<T>(v)
不调用std::vector
的move构造函数。它调用copy构造函数。您需要显式地将v
转换为右值来做正确的事情:
Vec(Vec&& v) : std::vector<T>(std::move(v)) { }
explicit Vec(std::vector<T>&& v): std::vector<T>(std::move(v)) { }
或者更好:
Vec(Vec&& ) = default;
类似地,编写赋值操作符的万无一失的方法只是将它们default
:
Vec& operator=(Vec const& ) = default;
Vec& operator=(Vec&& ) = default;
但是如果你真的有特殊的逻辑,确保你也记得在那里转换为右值:
Vec& operator=(Vec&& v) {
std::vector<T>::operator=(std::move(v));
// stuff
return *this;
}
或者更好的是,将您的特殊逻辑移动到一个独立的单元中,这样default
-ing仍然是正确的。
相关文章:
- 为什么此派生对象无法访问基类的后递减方法?
- 无法访问基类函数 C++
- 相同的层次结构,访问基类的受保护成员时的行为不同
- 如何访问基类向量中的子类变量?(对于实体组件系统)
- 如何从派生类访问基类中的重载运算符?
- 派生类无法访问基类的受保护成员
- 我不能访问基类的函数
- 无法在赋值运算符中访问基类的受保护方法
- 访问基类中直接受保护的字段
- 使用单一实例类作为派生类时,如何访问基类中的函数
- 为什么无法访问基类的函数重载
- 访问基类的受保护成员
- 访问基类C 中的变量
- 尝试访问基类的受保护数据成员时出现编译错误
- 允许从特定派生类访问基类成员
- 如何通过派生类访问基类的受保护成员?
- 在派生的C 类中,访问基类受保护成员作为公共的访问声明
- C++派生类访问基类成员
- 虚函数可以访问基类的友元吗?
- 使用派生模板化类的正确类型转换访问基类中的数据