const超载和多晶状体
Const overloading and polymorphysm
i具有const-overpolagon的登录成员函数(例如 operator[]
(:
class Container {
public:
Foo& operator[](int i);
const Foo& operator[](int i) const{
return const_cast<Container *>(this)->operator[](i);
}
};
在这里,const Foo& operator[] const
以这种方式定义,因此未定义两次。
现在我想让Container
成为基类,而operator[]
变为虚拟:
class BaseContainer {
public:
virtual Foo& operator[](int i) = 0;
const Foo& operator[](int i) const{
// Is this correct?
return const_cast<BaseContainer *>(this)->operator[](i);
}
};
class DerivedContainer : public BaseContainer {
public:
Foo& operator[](int i);
};
由于const_cast
从const DerivedContainer *
到BaseContainer *
是非法的,所以我不确定在多态性的情况下是否有效。
我认为铸件仍然有效,因为this
的类型始终是BaseContainer::operator[] const
中的const BaseContainer *
,因为它不是虚拟的,但是我不确定这是否是正确的方法。也许在这种情况下两次定义operator[]
是最好的?
会假设
const_cas
T仍然有效,因为它的类型始终是BaseContainer::operator[] const
中的const BaseContainer *
,因为它不是virtual
,但是我不确定这是否是正确的方法。
您的理解是正确的。该代码应按预期工作。
不过,您必须考虑另一件事。当您声明
时Foo& operator[](int i);
在派生类中,如果在派生的类对象/参考/指针上进行函数调用,则找不到const
版本。要能够与派生的类对象/参考/指针一起使用,请在派生类中添加以下内容。
using BaseContainer::operator[];
由于多态性,DerivedContainer
中CC_17中的过载的非cont-version将被调用。因此,从这一点开始,它实际上是一种"法律"设计,尽管您的假设"这始终是basecontainer :: operator [] const中的const basecontainer *,因为它不是虚拟的,因为它是 - 在多态性的背景下 - 错误。
请参阅以下说明呼叫链的代码:
struct Base {
virtual void print() { cout << "Base.non-const;"; }
void print() const { cout << "entry:Base.const;then..."; const_cast<Base *>(this)->print(); }
};
struct Derived : public Base {
void print() override { cout << "Derived.non-const;"; }
};
int main() {
const Base* bc = new Derived;
bc->print();
//Output: entry:Base.const;then...Derived.non-const;
cout << endl;
Base* bnc = new Derived;
bnc->print();
// Output: Derived.non-const;
}
请注意,如果该对象最初定义为const
,则operator[]
的非统计体不得更改*this
-Object。否则您会得到未定义的行为。
- 寻找地理和伤害意味着超载
- 没有可行的超载'='用于shared_ptr
- "专业化不参与超载"
- 虚拟超载运算符>>和<<
- 为什么我的超载"+"运算符返回的总额错误?
- C++ 超载 += 用于两个袋子的合并,返回类型为空隙
- C++11 中对超载'ref(Select::Expressions::Code&)'的调用模棱两可
- 为什么STD :: SPAN超载函数调用操作员索引
- C 操作员超载调用驱动器
- C const char *评估操作员超载
- 如何包括C 模板类的非成员运算符 - 超载
- 类型长的长度和未解决的超载函数类型的类型的操作数与二进制运算符
- 无法调用纯抽象基类超载
- 二进制超载操作员=
- 操作员超载;必须是二进制操作员(具有3个参数)
- 如果我具有调用其其他实例之一的超载函数,它是否被认为是递归功能
- 超载 =具有多个术语的运算符
- GLM超载操作员用于地图不起作用
- C bool表达式作为函数参数调用错误的超载
- const超载和多晶状体