C++一道考题
题目如下,运行结果是DBB。可是我想不通最后一个B是怎么来的。d不是派生类D的对象吗?为什么fun3(d);调用的是基类的虚函数?明天考试,今晚突击中。急,在线等#inc...
题目如下,运行结果是DBB。可是我想不通最后一个B是怎么来的。d不是派生类D的对象吗?为什么fun3(d);调用的是基类的虚函数?
明天考试,今晚突击中。急,在线等
#include<iostream>
using namespace std;
class B{
public:
virtual void Show(){cout<<'B';}
};
class D:public B{
public:
void Show(){cout<<'D';}
};
void fun1(B* ptr){ptr->Show();}
void fun2(B& ref){ref.Show();}
void fun3(B b){b.Show();}
int main(){
B b,*p=new D;
D d;
fun1(p);
fun2(b);
fun3(d);
return 0;
} 展开
明天考试,今晚突击中。急,在线等
#include<iostream>
using namespace std;
class B{
public:
virtual void Show(){cout<<'B';}
};
class D:public B{
public:
void Show(){cout<<'D';}
};
void fun1(B* ptr){ptr->Show();}
void fun2(B& ref){ref.Show();}
void fun3(B b){b.Show();}
int main(){
B b,*p=new D;
D d;
fun1(p);
fun2(b);
fun3(d);
return 0;
} 展开
4个回答
展开全部
显然你没有理解继承,多态
临时充电
继承:
class A
{
speak(){aaa}
}
class B:public A
{
speak(){bbb}
}
声明:B b,因为在构造b的时候,要先构造它的父类对象
于是对b来说,它有两个speak()
只是它现在是b对象,而看不到A的speak(),就像变量在语句块内外一样,不在它的作用域范围,于是b.speak输出bbb
那么既然B包含了A的speak(),那在哪里呢?可以将B强制转换成A,然后调用speak() ((A)b).speak()
而virtual又不一样了
class A
{
virtual speak(){aaa}
}
class B:public A
{
speak(){bbb}
}
此时声明B b,由于virtual是改写
那么构造b之前需要构造基类对象,由于是改写,那么此时对b来说只有一个speak(),那么将b强制转换成A类型,((A)b.speak()还是输出bbb,因为它根本就只有b中的speak(),怎么调用都只有一个
所以分析你的题目
fun1(p);
就是类型((A)b).speak,由于使用virtual改写,肯定输出D (derive)派生
fun2(b);
b是A类型,那么根本就没有继承,肯定是输出B (base) 基类
fun3(d);
这个函数显然有意思fun3(B b)调用fun3(d)
这个过程是这样的声明B b形参,然后将d赋值给b,即b=d,赋值与强制转换不一样,赋值仅仅进行成员变量的拷贝,与成员函数一点关系都没
那么在函数fun3函数体中使用b,它就是一个Base对象,那么肯定输出都是B(Base)
明白了吗?
临时充电
继承:
class A
{
speak(){aaa}
}
class B:public A
{
speak(){bbb}
}
声明:B b,因为在构造b的时候,要先构造它的父类对象
于是对b来说,它有两个speak()
只是它现在是b对象,而看不到A的speak(),就像变量在语句块内外一样,不在它的作用域范围,于是b.speak输出bbb
那么既然B包含了A的speak(),那在哪里呢?可以将B强制转换成A,然后调用speak() ((A)b).speak()
而virtual又不一样了
class A
{
virtual speak(){aaa}
}
class B:public A
{
speak(){bbb}
}
此时声明B b,由于virtual是改写
那么构造b之前需要构造基类对象,由于是改写,那么此时对b来说只有一个speak(),那么将b强制转换成A类型,((A)b.speak()还是输出bbb,因为它根本就只有b中的speak(),怎么调用都只有一个
所以分析你的题目
fun1(p);
就是类型((A)b).speak,由于使用virtual改写,肯定输出D (derive)派生
fun2(b);
b是A类型,那么根本就没有继承,肯定是输出B (base) 基类
fun3(d);
这个函数显然有意思fun3(B b)调用fun3(d)
这个过程是这样的声明B b形参,然后将d赋值给b,即b=d,赋值与强制转换不一样,赋值仅仅进行成员变量的拷贝,与成员函数一点关系都没
那么在函数fun3函数体中使用b,它就是一个Base对象,那么肯定输出都是B(Base)
明白了吗?
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
展开全部
fun3的参数类型是 B,所以你传入D后,由于D是public继承于B的,所以强制类型转换没有任何问题,所以调用的时候和虚函数无关。
和虚函数有关只有使用基类的指针或者引用才有可能。用基类的对象是不会涉及到虚函数的。
和虚函数有关只有使用基类的指针或者引用才有可能。用基类的对象是不会涉及到虚函数的。
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
展开全部
当然是因为fun3(B b)这里不是指针,也不是引用,所以调用的是基类的
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
展开全部
前两个你都清楚就不必分析了 重点分析最后一个
void fun3(B b)
这里b是形参 存在一个拷贝过程 执行函数体内的b.show()的时候
b已拷贝为B类型
而如果是使用B的引用 即
void fun3(B& b)
返回的就是你所希望的D了
void fun3(B b)
这里b是形参 存在一个拷贝过程 执行函数体内的b.show()的时候
b已拷贝为B类型
而如果是使用B的引用 即
void fun3(B& b)
返回的就是你所希望的D了
本回答被提问者采纳
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
推荐律师服务:
若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询