diningphil
diningphil

Reputation: 446

Mistake when overriding C++ virtual function

This is my situation:

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
  }
};

Now, when I call:

Filter3by3 f = choose_filter(filtername); // Returns a Sobel filter
Mat mat;
s.convolution(args);

The base class method is called. I am quite newbie at c++ method binding rules, so can you tell me where I am wrong? I appreciate your help.

UPDATE It appears that even with virtual inline Mat convolution((Mat & mat, int i, int j, int rows, int cols) It does not work.

This is a running program, compiled with 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;
  }

It prints 1 instead of 2. I used virtual to ensure dynamic binding, but it does not seem to be enough, also with "override" keyword.

Upvotes: 3

Views: 351

Answers (3)

w1ck3dg0ph3r
w1ck3dg0ph3r

Reputation: 1011

When you assign an object of derived class to an object of base class like that, you not achieving dynamic dispatch, you achieve slicing (all of the additional data members of SubFilter are lost)

  Filter choose_filter(){
    SubFilter f;
    return f;
  }

Instead you should pass it by (safe) pointer or reference, like this:

  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;
  }

Upvotes: 1

Guillaume Racicot
Guillaume Racicot

Reputation: 41770

There's a keyword in c++ called override. It exactly solve the problem you mentioned:

struct MySobe l: Filter3by3 {
    inline Vec3b convolution(Mat & mat, int i, int j, int rows, int cols) override { code }
};

The presence of the override ensure that the method really overrides the base class method.

In your code, it will cause a compilation error because the derived class does not overrides, since the signature are different.

Upvotes: 1

The Techel
The Techel

Reputation: 873

An overridden method has to have the same signature, i.e. argument and return types, as the base method. The compiler can notify you if these do not match if you add the override keyword to the signature.

Upvotes: 6

Related Questions