#include<iostream>  
using namespace std;  
class MyClass {  
  public:  
     MyClass(int i=0) {  
       cout<<i;  
     }  
     MyClass(const MyClass &x) {  
       cout<<2;  
     }  
     MyClass&operator=(const MyClass &x) {  
       cout<<3;  
       return*this;  
     }  
     ~MyClass(){  
       cout<<4;  
     }  
      
};  
int main()  
{  
  MyClass obj1(1),obj2(2);  
  MyClass obj3=obj1;  
  return 0;  
}  

  

分析一:

1.调用obj1的构造函数MyClass(int i =0)输出1;
2.调用obj2的构造函数MyClass(int i = 0)输出2;
3.调用obj3的复制构造函数MyClass(const MyClass&x)输出2;
4.main函数返回时分别调用obj3、obj2、obj1的析构函数输出444;

 

分析二:

若main函数中改成: MyClass obj1(1), obj2(2); MyClass obj3; obj3 = obj1; 最后执行的结果为:1203444 也就是说:拷贝构造函数发生在对象还没有创建;赋值操作符重载仅发生在对象已经创建的情况下。

 

分析三:

拷贝构造函数发生在对象还没有创建,需要创建时,如obj3;赋值操作符重载仅发生在对象已经执行过构造函数,即已经创建的情况下

 

前两个对象构造时分别输出1,2

第三个对象是这样构造的MyClassobj3 = obj1,之前没有执行过构造函数创建对象,所以这里会调用拷贝构造函数,输出2

然后三个对象依次析构,输出444

所以最终输出122444

 

#include<iostream>
using namespace std;
class B0 {
  public:
     virtual void  display() {
       cout<<"B0::display0"<<endl;
     }
};
 
class B1:public B0 {
  public:
     void display() {
       cout<<"D1::dispaly0"<<endl;
     }
};
 
class D1:public B1 {
  void display() {
     cout<<"D1::display0"<<endl;
  }
};
void fun(B0 ptr) {
  ptr.display();
}
 
 
int main()
{
  B0 b0;
  B1 b1;
  D1 d1;
  fun(b0);
  fun(b1);
  fun(d1);
  return 0;
}

  

分析:虚函数的动态绑定仅在 基类指针或引用绑定派生类对象时发生,fun的形参不是指针,所以调用哪个版本的函数编译时就已经确定,根据形参静态类型确定调用B0的成员。

 

此题的关键点在于fun函数,传入的参数是一个类的对象,这样,派生类作为参数传入的时候,会自动的类型转换为基类对象,这样,display就只是执行基类的函数了。打印B0::display()B0::display() B0::display()

 

这里使用的不是按地址传递,这样会转化为基类对象,直接调用基类的成员函数,如果是指针传递,改为B0 *ptr,

ptr->display(),可以实现多态。

posted on 2017-09-04 14:13  王小东大将军  阅读(314)  评论(0编辑  收藏  举报