1 在C++ 中多态性体现在哪几方面?
答案:
在C++中,多态性体现在两个方面:
编译多态性——对同一消息的不同操作是在程序编译时就确定了,即静态多态性。
运行多态性——对同一消息的不同操作是在程序运行时根据不同的运行状况才确定,即动态多态性。
2 函数重载与虚函数有哪些相同点与不同点?
答案:
函数重载与虚函数之间的相同点是多个函数版本具有相同的函数名,即表现出对同一消息的不同操作。而二者之间的不同点表现在:
⑴函数重载的不同函数版本既允许存在于同一类中,也允许基类的成员函数在派生类中重
载。存在于同一类中的不同重载函数版本的参数(类型、个数、顺序)必须有所不同。
如果存在于基类和派生类中的成员函数的原型完全一致,则派生类的成员函数将覆盖基类的同名函数。
⑵虚函数是用来表现基类和公有派生类的相同原型成员函数之间的关联关系的实现机制,
因此这种同原型成员函数必须分属于基类和派生类,并且首先在基类中用关键字virtual 声明虚函数;一个虚函数一旦被定义,就可以在该基类的一个或多个直接或间接派生类中被重新定义;虚函数重新定义时,其函数原型,即包括返回类型、函数名、参数的类型、个数和顺序,都必须与基类中的原型完全一致。
3 虚函数是如何实现面向对象系统的多态性的,它会带来什么益处?
答案:
在一个具有公有派生关系的类层次结构中,只要在基类中将某个接口函数声明为虚函数,并在该基类的直接和间接公有派生类中重新定义该虚函数的不同新版本,就可以实现在程序运行期间,使用一个基类指针动态地指向基类和从该基类直接或间接派生的任何类的对象,并通过该指针调用虚函数在不同类中定义的不同版本,即动态多态性。显然,虚函数为面向对象系统提供了一种更为灵活的多态性,这种多态能力对于期望在基类中为从该基类派生的所有类定义统一的操作接口的设计尤为重要。
4 下面有两段程序,判断它们是否正确,若有错误,给予纠正。
多态性与虚函数
①class base
{
// …
public:
virtual void show();
};
class derive : public base
{
// …
public:
void show();
};
main()
{
base obj1, obj2, *ptr1;
derive obj3, obj4, *ptr2;
ptr1 = &obj1;
ptr1->show();
ptr1 = &obj3;
ptr1->show();
ptr2 = &obj4;
ptr2->show();
ptr2 = &obj2;
ptr2->show();
// …
}
②class fruit
{
// …
public:
virtual void show() = 0;
// …
};
class apple : public fruit
{
// …
public:
void show();
// …
};
main()
{
fruit fru, *ptr;
apple app;
ptr = &app;
ptr->show();
ptr = &fru;
ptr->show();
// …
}
答案:
①该程序的main()中出现了使用派生类指针指向基类对象,并通过该指针调用基类虚函
数的错误语句(ptr2 = &obj2; ptr2->show();),因此,应该将main()修改为:
main()
{
base obj1, obj2, *ptr1;
derive obj3, obj4, *ptr2;
ptr1 = &obj1;
ptr1->show();
ptr1 = &obj3;
ptr1->show();
ptr2 = &obj4;或ptr1 = &obj4;
ptr2->show(); 或ptr1->show();
// …
}
②该程序的main()中出现了为抽象类fruit创建对象,并通过基类指针调用纯虚函数的错
误语句(fruit fru, ptr = &fru; ptr->show();),因此,应该将main()修改为:
main()
{
fruit *ptr;
apple app;
ptr = &app;
ptr->show();
// …
}
5 判断下列各段程序是否可以通过编译?为什么?
#include <iomanip.h>
class X
{
public:
X() { }
virtual void foo();
};
class Y : public X
{
public:
Y() { }
void foo() { cout << “Y’s foo invoked” << endl; }
};
int main() { return 0; }
答案:
由于基类中的虚函数没有定义实现代码,所以不能通过编译。修改方法有两种:
①为基类X中的虚成员函数增加空函数定义体:virtual void foo() {}
或者
②将基类X中的虚成员函数修改为纯虚函数:virtual void foo() = 0;
#include <iomanip.h>
class X
{
public:
X() { }
virtual void foo() = 0;
};
class Y : public X
{
public:
Y() { }
};
int main() { Y yobj; return 0; }
答案:
由于在派生类Y中没有为基类X的纯虚函数foo重新定义函数体,导致派生类Y仍然是抽象类,因此在main()中不能为Y创建对象yobj,所以该程序无法编译通过。修改方法有两种:
①在派生类Y中增加虚函数foo的定义:void foo() {}
或者
②将main()修改为:int main() { return 0; }
#include <iomanip.h>
class X
{
public:
X() { }
virtual void foo() = 0;
};
class Y : public X
{
public:
Y() { }
void foo() { cout << “Y’s foo invoked” << endl; }
};
int main() { Y yobj; return 0; }
答案:
该程序可以编译通过。

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。