在派生类和切片中使用运算符=的正确方式
Proper way to use operator = in derived class and slicing
所以我有一个基类,它有一个私有成员,还有一个派生类,它也有一些成员,基类定义了一个运算符=,这就是我的问题:
这是正确的方法吗?还是有更好的方法?一路上我要切片吗?
class A
{
private:
int* Arr;
public:
A(){
Arr=new int[10];
for(int i=0;i<10;i++){
Arr[i]=2*i;
}
}
const A& operator=(const A& a){
delete []Arr;
Arr=new int[10];
for(int i=0;i<10;i++){
Arr[i]=a.Arr[i];
}
return *this;
}
};
class B: public A
{
private:
int * Arr2;
public:
B(){
Arr2=new int[10];
for(int i=0;i<10;i++){
Arr2[i]=3*i;
}
}
const B& operator=(const B& b){
A::operator=(b);
delete []Arr2;
Arr2=new int[10];
for(int i=0;i<10;i++){
Arr2[i]=b.Arr2[i];
}
return *this;
}
};
我知道这不是一个完美的代码,但我只是为这个问题写了一个简单的代码。
经过大量研究,我得出了以下结论:
虽然使用基类分配运算符将正常工作
A::operator=(b)
代码仍然需要提供适当的异常安全、自分配安全如评论中所述的担保。
此外,由于我们需要实现一个赋值运算符,这也意味着根据三规则,我们需要实现复制构造函数,正如这里提到的,这将导致不必要的代码重复。
那么,我们如何解决所有这些问题(可能还有更多的问题)?我发现最好的原因是使用复制和交换习语。我认为,除了该帖子中提供的内容外,不需要进一步的解释。
您想要的不是类的层次结构。不可能指定给基础对象以获得派生对象的属性。基础对象将始终保持为基础对象。如果您希望具有多态性行为但保持合理的值语义,请将多态性封装在非多态性类中:
class A_impl;
class A {
public:
//Public interface:
//...
private:
//Assuming `value_ptr` similar to
//https://bitbucket.org/martinhofernandes/wheels/src/17aee21522ce8d07c7a74b138e528fadf04d62ed/include/wheels/smart_ptr/value_ptr.h%2B%2B?at=default
value_ptr<A_impl> impl;
};
class A_impl {
public:
//Implementation interface:
//virtual ...
//virtual ~A_impl() {}
};
class B : public A_impl {
public:
//Implementation:
//...
};
您应该编写复制构造运算符。
相关文章:
- C++ ->运算符 [] 的快捷方式
- C++:使用 std::unique_ptr 访问重载运算符++的最佳方式?
- 逗号运算符在对齐方式中
- 是否有快捷方式重叠运算符?
- 重载运算符是具有较小默认对齐方式的新增运算符
- 为什么三元运算符在编译时的工作方式与运行时不同?
- 对运算符删除覆盖的工作方式感到困惑
- 重载小于 (<) 运算符,用于以多种方式对对象进行排序
- 重载输入/输出运算符,为什么它以这种方式工作而不是以另一种方式工作
- Clang和g++处理运算符过载的方式不同
- 从BoostCon谈话中重载取消引用运算符的奇怪方式
- C++ 自定义运算符(+=) 的行为方式不可预测
- 运算符>>(,) 重载以令人惊讶的方式运行
- 比率类中的运算符/=以错误的方式工作
- 运算符 [] 和 insert() 函数在 C++ 映射中的行为方式不应该相同吗?
- 提供相同的ostream和wostream流运算符的任何快捷方式
- 复制构造函数未被调用,无法理解赋值运算符的工作方式
- C++ 字符串比较运算符>根据两个字符串的比较方式生成不同的输出
- 三元运算符是否以定义的方式短路
- 在派生类和切片中使用运算符=的正确方式