#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(),可以实现多态。
拥抱明天!
不给自己做枷锁去限制自己。
别让时代的悲哀,成为你人生的悲哀。