2

Is the following a case of static, or dynamic binding? Since I can know, what is the class of object my pointer is pointing to at compile time, my guess is that it is static...

class Base 
{
void print() const;
};

class Derived : public Base 
{
void print() const;
};

int main()
{
Base base;
Base *basePtr = &base;
basePtr->print();
}

And why we should use dynamic binding over static? I don't understand why we should use virtual functions instead of simply call a function in this way base.print() (for the example above). This method already "understand" which print() function call for the right class of the object, without using polymorphism and virtual functions.


Update

  // Point class definition represents an x-y coordinate pair.
  #ifndef POINT_H
  #define POINT_H

  class Point {

  public:
     Point( int = 0, int = 0 ); // default constructor

   void setX( int );  // set x in coordinate pair
   int getX() const;  // return x from coordinate pair

   void setY( int );  // set y in coordinate pair
   int getY() const;  // return y from coordinate pair

   virtual void print() const;  // output Point object

private: 
   int x;  // x part of coordinate pair
   int y;  // y part of coordinate pair

}; // end class Point

#endif

  // Circle class contains x-y coordinate pair and radius.
  #ifndef CIRCLE_H
  #define CIRCLE_H

  #include "point.h"  // Point class definition

  class Circle : public Point {

public:

   // default constructor
   Circle( int = 0, int = 0, double = 0.0 );  

   void setRadius( double );   // set radius
   double getRadius() const;   // return radius

   double getDiameter() const;       // return diameter
   double getCircumference() const;  // return circumference
   double getArea() const;           // return area

   virtual void print() const;       // output Circle object

private: 
   double radius;  // Circle's radius

}; // end class Circle

#endif 

  // Introducing polymorphism, virtual functions and dynamic
  // binding.
  #include <iostream>

  using std::cout;
  using std::endl;
  using std::fixed;

#include <iomanip>

using std::setprecision;

#include "point.h"   // Point class definition
#include "circle.h"  // Circle class definition

int main()
{
   Point point( 30, 50 );
   Point *pointPtr = 0;

   Circle circle( 120, 89, 2.7 );
   Circle *circlePtr = 0; 
  // set floating-point numeric formatting
   cout << fixed << setprecision( 2 );

   // output objects point and circle using static binding
   cout << "Invoking print function on point and circle "
        << "\nobjects with static binding "
        << "\n\nPoint: ";
   point.print();         // static binding
   cout << "\nCircle: ";
   circle.print();        // static binding

   // output objects point and circle using dynamic binding
   cout << "\n\nInvoking print function on point and circle "
        << "\nobjects with dynamic binding";

   // aim base-class pointer at base-class object and print
   pointPtr = &point;                                      
   cout << "\n\nCalling virtual function print with base-class"
        << "\npointer to base-class object"
        << "\ninvokes base-class print function:\n";
   pointPtr->print();
   // aim derived-class pointer at derived-class
   // object and print                          
   circlePtr = &circle;                         
   cout << "\n\nCalling virtual function print with "
        << "\nderived-class pointer to derived-class object "
        << "\ninvokes derived-class print function:\n";
   circlePtr->print();

   // aim base-class pointer at derived-class object and print
   pointPtr = &circle;                                        
   cout << "\n\nCalling virtual function print with base-class"
        << "\npointer to derived-class object "
        << "\ninvokes derived-class print function:\n";
   pointPtr->print();  // polymorphism: invokes circle's print
   cout << endl;

   return 0;

} // end main
Nerva
  • 309
  • 2
  • 13

3 Answers3

2

Is the following a case of static, or dynamic binding?

Static, since the function isn't virtual.

If it were virtual, then the function would be dispatched according to the dynamic type of the object.

And why we should use dynamic binding over static?

When we want to interact with objects of different types via a common base class, without knowing what the actual (dynamic) type is. For example,

class Base 
{
    virtual void print() const;  // add "virtual" to enable dynamic dispatch
};

// This function doesn't know the real (dynamic) type of the object,
// but still calls the correct version of "print".
void print(Base const & base) {
    // If "print" is virtual, then this calls the override for the dynamic type.
    // Otherwise, this calls Base::print.
    base.print();
}

int main() {
    Base base;
    Derived derived;

    print(base);     // calls Base::print
    print(derived);  // calls Derived::print
}

This method already "understand" which print() function call for the right class of the object, without using polymorphism and virtual functions.

Indeed, polymorphism isn't useful if, as in your example, you know the dynamic type already. It's for when you don't know the dynamic type, as in my example.

Mike Seymour
  • 235,407
  • 25
  • 414
  • 617
  • oh thank you!! You were so clear! I would like to give you +1 but I can't... However isn't "Static, since the function isn't virtual." a bit restrictive? Take a look at the program that leaves me so puzzled, that I've added. I don't understand why `point.print();` for example is static binding while `pointPtr->print();` is dynamic... – Nerva May 08 '14 at 14:50
  • @user3379939: `point.print()` is (probably) called statically, since the dynamic type of `point` is known to be `Point` - there's no need for dynamic dispatch. `pointPtr->print()` might be called dynamically, since the compiler might not be smart enough to figure out the dynamic type. In any case, the result will be the same whether or not the compiler decides to use dynamic dispatch. – Mike Seymour May 08 '14 at 15:21
1

There is no any dynamic binding in your example. You simply defined a pointer of the type of the base class and assigned it an address of an object of the (same) base class. So it is not clear why you are speaking about dynamic binding.

Also the definition of the derived class is used nowehere.

Dynamic binding is used when the static type of a pointer or a reference does not coinside with its dynamic type and when there is used a virtual function. In your example there is no the first requirement nor the second.

Here is an example of dynamic binding

#include <iostream>

class Base 
{
   virtual void print() const { std::cout << "Base" << std::endl; }
   virtual ~Base() = default;
   // or virtual ~Baae() {}
};

class Derived : public Base 
{
   void print() const { std::cout << "Derived" << std::endl; }
};

int main()
{
   Derived d;
   Base *basePtr = &d;
   basePtr->print();
}

Though static type of pointer basePtr is Base * its dynamic type is Derived * because it was assigned by the address of an object of the derived class.

It will be useful to cite a note from the C++ Standard that it would be more clear

[ Example: if a pointer (8.3.1) p whose static type is “pointer to class B” is pointing to an object of class D, derived from B (Clause 10), the dynamic type of the expression *p is “D.” References (8.3.2) are treated similarly. —end example ]

Vlad from Moscow
  • 224,104
  • 15
  • 141
  • 268
0

Dynamic binding occurs when using virtual methods. Base::print is not virtual. The idea of dynamic binding is the actual method that will be called is bound at run time, and this occurs when a derived class overrides a virtual method in base class, then depending on the actual object class (base/derived), the method gets bound. In fact defining method in derived class with same name as base class hides the base class method, and this is a bad practice.

Rakib
  • 6,975
  • 6
  • 24
  • 43