Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Does a virtual keyword with operator()() make sense? (functors)

Consider I have a hierarchy defined as below

class Strategy
{
public:
    virtual void Run();
};
class StrategyA : public Strategy
{
public:
    virtual void Run();
};
class StrategyB : public Strategy
{
public:
    virtual void Run();
};

I was wondering if I replace the Run() with operator() makes any sense and if there are any advantages from a design and efficiency perspective.

class Strategy
{
public:
    virtual void operator()();
};
class StrategyA : public Strategy
{
public:
    virtual void operator()();
};
class StrategyB : public Strategy
{
public:
    virtual void operator()();
};

Thanks

CV.

like image 694
Chenna V Avatar asked Sep 13 '11 14:09

Chenna V


People also ask

Can C++ operators be virtual?

Assignment Operator in C++ can be made virtual.

Is virtual keyword necessary?

The virtual keyword can be used when declaring overriding functions in a derived class, but it is unnecessary; overrides of virtual functions are always virtual. Virtual functions in a base class must be defined unless they are declared using the pure-specifier.

What is the purpose of the virtual keyword in C++?

A virtual function in C++ is a base class member function that you can redefine in a derived class to achieve polymorphism. You can declare the function in the base class using the virtual keyword.

Which is not true about virtual function in C++?

​Hence, Virtual functions cannot be static in C++.


1 Answers

Yes. Its fully makes sense.

Any operator overload is a function, after all. It adds syntactic sugar to the language. Sometimes, they're necessary, but often, it's just syntactic sugar.

Note that you've to invoke it polymorphically (of course, if you want runtime-polymorphism), and there're two ways you can do that:

  • using pointer of base type, and
  • using reference of base type

Example (demo),

struct A
{
   virtual void operator()() { cout << "A" << endl; }
};
struct B : A
{
   virtual void operator()() { cout << "B" << endl; }
};

int main() {
        B b;

        //using pointer
        A *ptr = &b;
        (*ptr)(); //clumsy!  - prints B

        //using reference
        A &ref = b;
        ref();   //better    - prints B

        //also correct
        b();  //prints B
        return 0;
}

And if you've a function template written as:

template<typename Functor>
void call(Functor fun)
{
   (*fun)();
}

Then you can use this function, for functors and regular functions, both:

void regular_function()
{
   cout << "regular_function" << endl;
}

B b;
call(&b);  //prints B
call(regular_function); //prints regular_function

Demo : http://ideone.com/B9w16

like image 62
Nawaz Avatar answered Nov 15 '22 21:11

Nawaz