(筆記試験問題)C++の虚関数と多態性について
2840 ワード
次の2つのプログラムの出力は何ですか?
プログラム1:
分析:
答え:100 50
Derived Obj;
Base *pObj = &Obj;
printf("%d,", pObj->Bar((char)(100)))
printf("%d,", pObj->Bar(100));
最初のBar(char)は非虚関数であるため静的バインディングであり,静的バインディングはポインタが宣言時のオブジェクトを指し,pObj宣言時はBaseクラスであるため,BaseクラスのBar(char)が呼び出される.
2番目のBar(char)は虚関数であるため動的バインディングであり,動的バインディングはポインタが参照するオブジェクトを指し,pObjはDerivedオブジェクトを参照するためDerivedクラスのBar(int)を呼び出す.
プログラム2:
分析:
答え:Miao,my age=2
int*p = (int*)(&kitty);
int*q = (int*)(&jd);
pとqはそれぞれkittyとjdの2つのオブジェクトを指すヘッダアドレスであり、クラスCatとDogはいずれも虚関数を含むため、kittyとjdの2つのオブジェクトはいずれも虚関数テーブルを含み、1つのポインタでそれを指し、p[0]とq[0]はこの虚関数テーブルポインタであり、p[1]とq[1]はこの対象のデータメンバーであるageの値であり、p[1]=1、q[1]=2である
p[1] = q[1]=2;
kittyのageは2に変更され、
animal *pa;
pa = &kitty;
pa->print_age();
paポインタ宣言時のタイプはベースクラスanimalであり、派生クラスkittyオブジェクトを指し、典型的なマルチステート特性ではpaの静的タイプはanimal、動的タイプはcatである.
そしてprint_age()は虚関数であるため動的バインドであり、動的バインドは動的タイプのメンバーを指すためkittyのメンバー関数print_が呼び出されるage(),
cout << "Miao,my age= " << this->age << endl;
このときage=2.
プログラム1:
#include "stdio.h"
class Base
{
public:
int Bar(char x)
{
return (int)(x);
}
virtual int Bar(int x)
{
return (2 * x);
}
};
class Derived : public Base
{
public:
int Bar(char x)
{
return (int)(-x);
}
int Bar(int x)
{
return (x / 2);
}
};
int main(void)
{
Derived Obj;
Base *pObj = &Obj;
printf("%d,", pObj->Bar((char)(100)));
printf("%d,", pObj->Bar(100));
}
分析:
答え:100 50
Derived Obj;
Base *pObj = &Obj;
printf("%d,", pObj->Bar((char)(100)))
printf("%d,", pObj->Bar(100));
最初のBar(char)は非虚関数であるため静的バインディングであり,静的バインディングはポインタが宣言時のオブジェクトを指し,pObj宣言時はBaseクラスであるため,BaseクラスのBar(char)が呼び出される.
2番目のBar(char)は虚関数であるため動的バインディングであり,動的バインディングはポインタが参照するオブジェクトを指し,pObjはDerivedオブジェクトを参照するためDerivedクラスのBar(int)を呼び出す.
プログラム2:
#include <iostream>
using namespace std;
class animal{
protected:
int age;
public:
virtual void print_age(void) = 0;
};
class dog : public animal{
public:
dog(){ this->age = 2; }
~dog(){}
virtual void print_age(void){ cout << "wang. my age=" << this->age << endl; }
};
class cat:public animal{
public :
cat(){ this->age = 1; }
~cat(){}
virtual void print_age(void){ cout << " Miao,my age= " << this->age << endl; }
};
int main(void){
cat kitty;
dog jd;
animal *pa;
int *p = (int *)(&kitty);
int *q = (int *)(&jd);
//cout << p[1] << endl;
//cout << q[1] << endl;
p[1] = q[1];
pa = &kitty;
pa->print_age();
return 0;
}
分析:
答え:Miao,my age=2
int*p = (int*)(&kitty);
int*q = (int*)(&jd);
pとqはそれぞれkittyとjdの2つのオブジェクトを指すヘッダアドレスであり、クラスCatとDogはいずれも虚関数を含むため、kittyとjdの2つのオブジェクトはいずれも虚関数テーブルを含み、1つのポインタでそれを指し、p[0]とq[0]はこの虚関数テーブルポインタであり、p[1]とq[1]はこの対象のデータメンバーであるageの値であり、p[1]=1、q[1]=2である
p[1] = q[1]=2;
kittyのageは2に変更され、
animal *pa;
pa = &kitty;
pa->print_age();
paポインタ宣言時のタイプはベースクラスanimalであり、派生クラスkittyオブジェクトを指し、典型的なマルチステート特性ではpaの静的タイプはanimal、動的タイプはcatである.
そしてprint_age()は虚関数であるため動的バインドであり、動的バインドは動的タイプのメンバーを指すためkittyのメンバー関数print_が呼び出されるage(),
cout << "Miao,my age= " << this->age << endl;
このときage=2.