基类中的运算符重载问题
Posted
技术标签:
【中文标题】基类中的运算符重载问题【英文标题】:trouble with operator overloading in baseclass 【发布时间】:2014-05-09 16:23:01 【问题描述】:您好,我在继承和运算符重载方面遇到了一些问题,希望你们能给我一些说明。
我有以下课程:
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;
【问题讨论】:
'现在我希望我的所有谓词都接受引用和指针' 可能这个return (*this)(*value);
应该使用适当的static_cast<>
然后...
【参考方案1】:
这是因为当你声明时:
bool operator()(const Type & value)return true;
在子类中,您隐藏/隐藏超类中运算符的任何其他重载。
如果你添加:
using Predicate<Type>::operator();
Live demo
在子类中,一切都会正常工作。
另一方面,我认为同时允许 const&
和 const*
是一种设计味道。您应该只允许 const&
版本,如果您的班级用户有 ptr
指针,则让他们执行 *ptr
。
【讨论】:
我完全同意关于设计气味的评论,尽管我在自己的回答中没有提到它。还有一些其他问题,例如使用system("pause");
。
您好,感谢您的回答,这是作业的一部分,学习额外的东西总是好的。谓词将用于 vector模板和运算符重载混淆了这里的真正问题。看看这段产生相同错误的小代码:
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;
这编译得很好,因为基类运算符现在被考虑用于重载解决方案。但这只是为了让您更好地理解问题。 解决方案是应用Non-Virtual Interface Idiom。使您的操作员成为非虚拟的,并根据私有虚拟功能实现它们:
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;
;
【讨论】:
以上是关于基类中的运算符重载问题的主要内容,如果未能解决你的问题,请参考以下文章