这是我的情况:
class Filter3by3 {
public:
virtual inline Mat convolution((Mat & mat, int i, int j, int rows, int cols) {
code
}
};
class MySobel: public Filter3by3 {
public:
inline Vec3b convolution(Mat & mat, int i, int j, int rows, int cols) {
code
}
};
现在,当我打电话:
Filter3by3 f = choose_filter(filtername); // Returns a Sobel filter
Mat mat;
s.convolution(args);
调用基类方法。 我是c ++方法绑定规则的新手,所以你能告诉我哪里错了吗? 感谢您的帮助。
更新 它似乎即使有了 虚拟内联Mat卷积((Mat& mat,int i,int j,int rows,int cols) 它不起作用。
这是一个正在运行的程序,用g ++ -std = c ++ 11
编译#include <iostream>
using namespace std;
class Filter {
public:
Filter() { }
virtual int ehi() {
cout << "1" << endl;
return 1;
}
};
class SubFilter : public Filter {
public:
SubFilter() : Filter() { }
int ehi() {
cout << "2" << endl;
return 2;
}
};
Filter choose_filter(){
SubFilter f;
return f;
}
int main(int argc, char* argv[]) {
Filter f = choose_filter();
f.ehi();
return 0;
}
它打印1而不是2.我使用虚拟来确保动态绑定,但它似乎不够,还有“覆盖”关键字。
答案 0 :(得分:6)
重写方法必须具有相同的签名,即参数和返回类型,作为基本方法。如果您将 override 关键字添加到签名中,编译器可以通知您这些不匹配。
答案 1 :(得分:1)
c ++中有一个名为override
的关键字。它完全解决了你提到的问题:
struct MySobe l: Filter3by3 {
inline Vec3b convolution(Mat & mat, int i, int j, int rows, int cols) override { code }
};
override
的存在确保该方法真正覆盖基类方法。
在您的代码中,它会导致编译错误,因为派生类不会覆盖,因为签名不同。
答案 2 :(得分:1)
当您将派生类的对象分配给基类的对象时,如果没有实现动态调度,则实现slicing(SubFilter
的所有其他数据成员都将丢失)< / p>
Filter choose_filter(){
SubFilter f;
return f;
}
相反,你应该通过(安全)指针或引用传递它,如下所示:
std::shared_ptr<Filter> choose_filter(){
return std::make_shared<SubFilter>();
}
int main(int argc, char* argv[]) {
auto f = choose_filter();
f->ehi();
return 0;
}