显式转换与隐式转换
下面哪种情况下,B不能隐式转换为A?
class B:public A{}
class A:public B{}
class B{operator A();}
class A{A(const B&);}
显式转换是由程序员自己主动完成,隐式转换是由编译器完成的,其二显示转换一般是由高向低,隐式转换是由低到高,其三显式转换的格式为类型(对象)或(类型)对象。
static_cast, dynamic_cast, const_cast探讨
- 用于类层次结构中基类和子类之间指针或引用的转换。进行上行转换(把子类的指针或引用转换成基类表示)是安全的;进行下行转换(把基类指针或引用转换成子类指针或引用)时,由于没有动态类型检查,所以是不安全的。
public之后的是基类,A中A是基类,B是派生类,B转A的时候会产生切片问题,是可行的;
表示A是基类,B是派生类,向上级类型转换是隐式的,因为部分元素丢弃可以自动完成,向下转型是显式的因为不知道应该增加的值是什么。所以B不能。
答案C,Operator除了表示函数重载操作符,还可以表示B类型可以装换为A类型。
B中B是基类,A是派生类,因为A中有B中不存在的部分,隐式转换会发生问题,可以采用强制类型转换dynamic_cast<A> b;
C不太清楚,但可以肯定B错
D是复制构造函数,楚翔a=b;的时候可以调用,故可以隐式转换;
1 #include<iostream> 2 using namespace std; 3 class B0//基类BO声明 4 { 5 public://外部接口 6 virtual void display()//虚成员函数 7 { 8 cout<<"B0::display0"<<endl;} 9 }; 10 class B1:public B0//公有派生 11 { 12 public: 13 void display() { cout<<"B1::display0"<<endl; } 14 }; 15 class D1: public B1//公有派生 16 { 17 public: 18 void display(){ cout<<"D1::display0"<<endl; } 19 }; 20 void fun(B0 ptr)//普通函数 21 { 22 ptr.display(); 23 } 24 int main()//主函数 25 { 26 B0 b0;//声明基类对象和指针 27 B1 b1;//声明派生类对象 28 D1 d1;//声明派生类对象 29 fun(b0);//调用基类B0函数成员 30 fun(b1);//调用派生类B1函数成员,子类向上隐式类型转换为父类 31 fun(d1);//调用派生类D1函数成员,子类向上隐式类型转换为父类 32 }
B0::display() B0::display() B0::display()
B0::display() B0::display() D1::display()
B0::display() B1::display() D1::display()B0::display() B1::display() B1::display(
虚函数的动态绑定仅在 基类指针或引用绑定派生类对象时发生 ,fun的形参不是指针,所以调用哪个版本的函数编译时就已经确定,
根据形参静态类型确定调用B0的成员。
此题的关键点在于fun函数,传入的参数是一个类的对象,这样,派生类作为参数传入的时候,会自动的类型转换为基类对象,
这样,display就只是执行基类的函数了。选B0::display() B0::display() B0::display()