基类中操作符重载的问题
trouble with operator overloading in baseclass
嗨,我在继承和操作符重载方面遇到了一些麻烦,我希望你们能给我一些清晰的解释。
我有以下类:
template<typename Type>
class Predicate{
public:
Predicate() {};
virtual ~Predicate(){};
virtual bool operator()(const Type & value) = 0;
virtual bool operator()(const Type * value){ //<-- this is the operator thats not working
return (*this)(*value);
};
};
template<typename Type>
class Always : public Predicate<Type>{
public:
bool operator()(const Type & value){return true;}
~Always(){};
};
现在我希望所有的谓词都接受引用和指针,但是当我在
中测试类时:int main(){
Always<int> a;
int i = 1000;
a(&i);
system("pause");
return 1;
}
我收到以下错误:
test.cpp: In function 'int main()':
test.cpp:10:6: error: invalid conversion from 'int*' to 'int' [-fpermissive]
a(&i);
^
In file included from test.cpp:2:0:
predicates.h:22:7: error: initializing argument 1 of 'bool Always<Type>::operator()(const Type&) [with Type = int]' [-fpermissive]
bool operator()(const Type & value){return true;}
这是因为当你声明:
bool operator()(const Type & value){return true;}
在子类中,您可以隐藏/遮蔽超类中操作符的任何其他重载。
如果您添加:
using Predicate<Type>::operator();
现场演示
在子类中,一切都会正常工作。
顺便说一句,我认为允许const&
和const*
是一种设计气味。你应该只允许const&
版本,让你的类的用户做*ptr
,如果他们有一个ptr
指针。
模板和操作符重载混淆了真正的问题。看看这一小段代码,它产生了同样的错误:
void f(int &);
int main()
{
int *ptr;
f(ptr);
}
编译器不允许在需要引用的地方传递指针。这就是您尝试对派生类所做的事情。当操作具体的Always
时,不考虑operator()
的基本版本。
看看在指向基类的指针(或引用)上操作时情况会发生什么变化:
int main(){
Predicate<int> *ptr = new Always<int>;
int i = 1000;
(*ptr)(&i);
delete ptr;
}
编译得很好,因为基类操作符现在被考虑用于重载解析。但这只是为了让你们更好地理解这个问题。解决方案是应用非虚接口习惯用法。使操作符非虚,并根据私有虚函数实现它们:
template<typename Type>
class Predicate{
public:
Predicate() {};
virtual ~Predicate(){};
bool operator()(const Type & value) { return operatorImpl(value); }
bool operator()(const Type * value) { return operatorImpl(value); }
private:
virtual bool operatorImpl(const Type & value) = 0;
virtual bool operatorImpl(const Type * value) {
return (*this)(*value);
}
};
template<typename Type>
class Always : public Predicate<Type>{
public:
~Always(){};
private:
bool operatorImpl(const Type & value){return true;}
};
相关文章:
- 一个关于在C++中重载布尔运算符的问题
- 在C++中使用重载提取运算符时出现问题
- 重载运算符与添加问题
- 加、乘、除、减复数的问题 C++ - 运算符重载
- 0xC0000005:访问冲突读取位置 0x00000000. 重载 == 运算符的问题
- 关于重载 -> 运算符中 const 关键字的特定位置的问题
- 基于 SFINAE 的特征实现问题与函数模板重载
- 关于在成员重载中使用 std::move() 的问题
- 字符 * 未从重载运算符或内存管理问题正确返回
- constexpr 运算符重载使用参数的问题
- c++中重载输入运算符的问题
- 在C++中写入 4D 矢量时遇到问题(没有可行的重载"=")
- 我的重载函数有什么问题?
- C++使用模板参数来解决重载问题
- C++ 中重载成员函数的问题
- 我想知道我将如何实现 + 运算符重载.我已经从我上一个问题中计算出 += 运算符重载
- 为什么C++在自定义结构向量时会出现 ostream 重载问题?
- 解决 CRTP 函数重载歧义问题
- C++:创建线程时出现问题;错误 C2672:"std::invoke":找不到匹配的重载函数
- C++重载构造函数问题