Before you understand static and dynamic bindings, learn what the static type of the object is and what is the dynamic type of the object.
- Static type of object: the type that the object takes when declaring. is determined by the compiler.
- Dynamic type of object: The type of object currently being referred to. is determined at run time.
Dynamic types can be changed, and static types cannot be changed. See an example
class Base
{
public:
void setData(int i=10)
{
cout <<" virtual int Base::setData()"<<endl;
}
virtual int getData()
{
cout <<" virtual int Base::getData()"<<endl;
}
private:
int m_value;
};
class Derive: public Base
{
public:
void setData(int i=20)
{
cout <<" virtual int Derive::setData()"<<endl;
}
virtual int getData()
{
cout <<" virtual int Derive::getData()"<<endl;
}
};
int _tmain(int argc, _TCHAR* argv[])
{
Derive *pd = new Derive;//pd的静态类型为Derive,动态类型也为Derive
Base *pb = pd; //pb的静态类型为Base,动态类型为Derive
return 0;
}
Figure out what is the static type of the object and what is the dynamic type of the object. Below is a description of what is static binding and what is dynamic binding.
- Static binding: The bound object is a static type. An attribute depends on the static type of the object, which occurs at compile time.
- Dynamic binding: The bound object is a dynamic type. There are attributes that depend on the dynamic type of the object, which occurs at run time.
Only virtual functions use dynamic bindings, and all others are static bindings.
We use PB,PD to call the non-virtual function separately,
derive * pd = new derive Span class= "pun";
base * PB = PD ;
PB -> setdata
pd -> setdata
Output:
Because SetData is statically bound, the compiler chooses the function at compile time based on the static type of the object.The static type of PB is base,pd static type is derive.
we use PD,PB to call virtual functions separately
Because GetData is a virtual function, it is dynamically bound. Dynamic types are derive*. The function of the base class and the function of the derived class are called separately.Note: Such a design is particularly bad, and a name masking occurs between the derived class and the base class. This is only written for static binding and dynamic binding. If the derived class and the base class are is-a relationships, do not inherit a non-virtual function under any circumstances.
Note: The dynamic type of pointers and references may be inconsistent with static types, but the static type of the object is consistent with the dynamic type. Derive d. D.setdata () D.getdata () is called a member function of a derived class.
When the virtual function has default parameters, the situation becomes a bit more complicated. Because the default parameter takes a static binding.
class Base
{
public:
virtual void getData(int i=10)
{
cout <<" virtual int Base::getData()" << i <<endl;
}
};
class Derive: public Base
{
public:
virtual void getData(int i = 20)
{
cout <<" virtual int Derive::getData()" << i <<endl;
}
};
int _tmain(int argc, _TCHAR* argv[])
{
Derive *pd = new Derive;
Base *pb = pd;
pb->getData();
pd->getData();
return 0;
}
Output:
Although the default parameters are called, the default parameters are static bindings. That's why it's going to get that way.to prevent this from happening: effective C + + specifically points out a:the inherited default parameters are never redefined. ToOne way to avoid this is to use NVI (Non-virtual interface): Declare a common non-virtual function in the base class and give the vacancy province parameter (because it is a static binding) in which the private virtual function is called, so that when the derived class method is called. Because a common non-virtual function takes a static binding, the derived class must inherit the non-virtual function. As a result, when the function is called, the default parameters are always available.
From for notes (Wiz)
C + + static binding and dynamic binding------never redefine inherited default parameters