The default setting in C ++ virtual functions

I read about the inheritance mechanism in C ++ and about virtual functions.

according to my knowlendge (in all the examples that I came across) the inherited methods had the same signature as the parent class.

My question is this: I know that the default value of a function parameter is not part of the function signature.

Can I define this value as a constant in the parent virtual function of the class, and in the derived class declare and implement an override method without this default value.

In this case, when I call the method of the derived object using a pointer to the parent class, the function is called with / without this initialization by default?

thank

+4
source share
2 answers

By default, arguments are mostly syntactic sugar and are determined at compile time. Virtual dispatch, on the other hand, is a run-time function. It would be perhaps the least surprising if this parameter were selected by default, which was defined together with the function that was actually called, but this is impossible (at least without additional utility utilities) for the reason indicated above.

Therefore, the default parameter is selected by the compiler using the static type of the object on which the member function is called. Consider an example.

#include <iostream>
#include <memory>

class Base
{

public:

  virtual void
  f(int a, int b = 1)
  {
    std::cout << "Base: a = " << a << ", b = " << b << "\n";
  }
};

class Derived : public Base
{

public:

  virtual void
  f(int a = 1, int b = 2) override
  {
    std::cout << "Derived: a = " << a << ", b = " << b << "\n";
  }
};

int
main()
{
  std::unique_ptr<Base> base_as_base {new Base {}};
  std::unique_ptr<Base> derived_as_base {new Derived {}};
  std::unique_ptr<Derived> derived_as_derived {new Derived {}};
  base_as_base->f(0);        // Base:    a = 0, b = 1
  derived_as_base->f(0);     // Derived: a = 0, b = 1
  // derived_as_base->f();   // compiler error
  derived_as_derived->f(0);  // Derived: a = 0, b = 2
  derived_as_derived->f();   // Derived: a = 1, b = 2
}

, . , . , . , , . protected . non virtual . , .

#include <iostream>
#include <memory>

class Base
{

public:

  void
  f(int a, int b = 1)
  {
    this->impl(a, b);
  }

protected:

  virtual void
  impl(int a, int b)
  {
    std::cout << "Base: a = " << a << ", b = " << b << "\n";
  }
};

class Derived : public Base
{

protected:

  virtual void
  impl(int a, int b) override
  {
    std::cout << "Derived: a = " << a << ", b = " << b << "\n";
  }
};

int
main()
{
  std::unique_ptr<Base> base_as_base {new Base {}};
  std::unique_ptr<Base> derived_as_base {new Derived {}};
  std::unique_ptr<Derived> derived_as_derived {new Derived {}};
  base_as_base->f(0);        // Base:    a = 0, b = 1
  derived_as_base->f(0);     // Derived: a = 0, b = 1
  derived_as_derived->f(0);  // Derived: a = 0, b = 1
}
+6

, ++ Draft N3337:

8.3.6

10 (10.3) , , . , . [:

struct A {
   virtual void f(int a = 7);
  };
  struct B : public A {
    void f(int a);
  };
 void m() {
   B* pb = new B;
   A* pa = pb;
   pa->f(); // OK, calls pa->B::f(7)
   pb->f(); // error: wrong number of arguments for B::f()
 }

-end ]

:

,

.

, , . , .

+2

All Articles