Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Good practice : Default arguments for pure virtual method

Tags:

c++

I have created an abstract base class, which has a pure virtual method with default argument.

class Base {
    ...
    virtual someMethod(const SomeStruct& t = 0) = 0;
    ...
}

class Derived : public Base {
    ...
    virtual someMethod(const SomeStruct& t = 0);
    ...
}

So I would like to know is it a good practice to set the default argument to pure virtual and overall to virtual methods?

like image 846
deimus Avatar asked Aug 27 '12 09:08

deimus


People also ask

Can pure virtual function have arguments?

Yes, C++ virtual functions can have default parameters.

What is friend and virtual function What are default arguments?

Default Arguments and Virtual Function in C++ In case any value is passed the default value is overridden and it becomes a parameterized argument. Virtual function is a member function that is declared within a base class and is redefined(Overridden) by a derived class.

What is the correct way to declare a pure virtual function?

You declare a pure virtual function by using a pure specifier ( = 0 ) in the declaration of a virtual member function in the class declaration. Class A is an abstract class. The compiler would not allow the function declarations A g() or void h(A) , declaration of object a , nor the static cast of b to type A .

What are the properties of pure virtual function?

A pure virtual function is a virtual function in C++ for which we need not to write any function definition and only we have to declare it. It is declared by assigning 0 in the declaration. An abstract class is a class in C++ which have at least one pure virtual function.


2 Answers

Actually, your code is one of worst possible usage patterns for default parameters, as it involves both inheritance and polymorphic behavior. I support an advice to have a look at related Scott Meyers tip, but here is a short overview:

In case of polymorphic calls, default parameters are used according to declaration for static type, not dynamic one. It is logical as run-time has no idea of default parameters, but breaks any sane assumptions about polymorphic behavior. For example,

#include <cstdio>

class Base
{
        public:
                virtual void f(int a = 1)
                {
                        printf("Base::f(%d)\n", a);
                }
};

class Deriv : public Base
{
        public:
                virtual void f(int a = 2)
                {
                        printf("Deriv::f(%d)\n", a);
                }
};

int main()
{
        Base* a = new Deriv();
        a->f();
        delete a;
        return 0;
}

yields:

Deriv::f(1)
like image 41
Mihails Strasuns Avatar answered Oct 02 '22 19:10

Mihails Strasuns


I often wish to use both default parameters and virtual function as you do. The others have rightfully pointed out however that this leads to ambiguity and is generally not a good idea. There is a reasonably simple solution, one that I use. Give your virtual function a different name, make it protected, and then provide a public function with default parameters which calls it.

class Base {
protected:
    virtual void vSomeMethod(const SomeStruct& t ) = 0;
public:
    void someMethod( const SomeStruc& t = 0 )
    { vSomeMethod( t ); }
}

Derived classes simply override vSomeMethod and don't worry at all about the default parameters.

like image 24
edA-qa mort-ora-y Avatar answered Sep 30 '22 19:09

edA-qa mort-ora-y