1.动态绑定:
通过基类的引用(或指针)调用虚函数时,发生动态绑定。
*继承层次的根类一般都要定义虚析构函数
*除构造函数外,任意非static成员函数都可以使虚函数
*保留字virtual只在类内部的成员函数声明中出现,不能用在类定义体外部出现的函数定义上
Example:
class A
{
public:
virtual void f()
{
cout<<"A.f()"<<endl;
}
virtual ~A(){ }
};
class B:public A
{
public:
void f()
{
cout<<"B.f()"<<endl;
}
};
int main()
{
A *a=new B;
a->f();//B.f(),通过基类的指针调用虚函数时,发生动态绑定
return 0;
}
Tips:
要触发动态绑定,必须满足两个条件:
(1)只有指定为虚函数的成员函数才能进行动态绑定
(2)必须通过基类类型的引用或指针进行函数调用
2.派生类和虚函数
*派生类必须对想要重定义的每个继承成员函数进行声明
*如果派生类没有重定义某个虚函数,则使用基类定义的版本
*一旦函数在基类中声明为虚函数,它就一直为虚函数
*派生类定义虚函数时,可以使用virtual保留字,但不是必须这么做
Example:
class A
{
public:
virtual void f()
{
cout<<"A.f()"<<endl;
}
};
class B:public A
{
public:
void f() //可以使用virtual保留字,但不是必须这么做
{
cout<<"B.f()"<<endl;
}
};
class C:public A
{
};
int main()
{
B b;
b.f();//B.f()
C c;
c.f();//A.f(),如果派生类没有重定义某个虚函数,则使用基类定义的版本
return 0;
}
3.用作基类的类必须是完全定义的
Example:
class base;
class derived:public base //error, invalid use of incomplete type 'class base'
{
};
4.覆盖虚函数机制
*使用作用域操作符可以覆盖函数机制并强制函数调用虚函数的特定版本
Example:
class base
{
public:
virtual void func()
{
cout<<"base.func()"<<endl;
}
};
class derived:public base //error
{
public:
virtual void func()
{
cout<<"derived.func()"<<endl;
}
};
int main()
{
derived *d = new derived;
d->func();//derived.func()
d->base::func();//base.func()
return 0;
}
通过基类的引用(或指针)调用虚函数时,发生动态绑定。
*继承层次的根类一般都要定义虚析构函数
*除构造函数外,任意非static成员函数都可以使虚函数
*保留字virtual只在类内部的成员函数声明中出现,不能用在类定义体外部出现的函数定义上
Example:
class A
{
public:
virtual void f()
{
cout<<"A.f()"<<endl;
}
virtual ~A(){ }
};
class B:public A
{
public:
void f()
{
cout<<"B.f()"<<endl;
}
};
int main()
{
A *a=new B;
a->f();//B.f(),通过基类的指针调用虚函数时,发生动态绑定
return 0;
}
Tips:
要触发动态绑定,必须满足两个条件:
(1)只有指定为虚函数的成员函数才能进行动态绑定
(2)必须通过基类类型的引用或指针进行函数调用
2.派生类和虚函数
*派生类必须对想要重定义的每个继承成员函数进行声明
*如果派生类没有重定义某个虚函数,则使用基类定义的版本
*一旦函数在基类中声明为虚函数,它就一直为虚函数
*派生类定义虚函数时,可以使用virtual保留字,但不是必须这么做
Example:
class A
{
public:
virtual void f()
{
cout<<"A.f()"<<endl;
}
};
class B:public A
{
public:
void f() //可以使用virtual保留字,但不是必须这么做
{
cout<<"B.f()"<<endl;
}
};
class C:public A
{
};
int main()
{
B b;
b.f();//B.f()
C c;
c.f();//A.f(),如果派生类没有重定义某个虚函数,则使用基类定义的版本
return 0;
}
3.用作基类的类必须是完全定义的
Example:
class base;
class derived:public base //error, invalid use of incomplete type 'class base'
{
};
4.覆盖虚函数机制
*使用作用域操作符可以覆盖函数机制并强制函数调用虚函数的特定版本
Example:
class base
{
public:
virtual void func()
{
cout<<"base.func()"<<endl;
}
};
class derived:public base //error
{
public:
virtual void func()
{
cout<<"derived.func()"<<endl;
}
};
int main()
{
derived *d = new derived;
d->func();//derived.func()
d->base::func();//base.func()
return 0;
}