Advertisement

C++ 多态 001:看上去像多态 002:Fun和Do 003:这是什么鬼delete 004:怎么又是Fun和Do

阅读量:

001:看上去像多态

描述
程序填空产生指定输出

复制代码
    #include <iostream>
    using namespace std;
    class B { 
    	private: 
    		int nBVal; 
    	public: 
    		void Print() 
    		{ cout << "nBVal="<< nBVal << endl; } 
    		void Fun() 
    		{cout << "B::Fun" << endl; } 
    		B ( int n ) { nBVal = n;} 
    };
    // 在此处补充你的代码
    int main() { 
    	B * pb; D * pd; 
    	D d(4); d.Fun(); 
    	pb = new B(2); pd = new D(8); 
    	pb -> Fun(); pd->Fun(); 
    	pb->Print (); pd->Print (); 
    	pb = & d; pb->Fun(); 
    	pb->Print(); 
    	return 0;
    }

输入

输出

复制代码
    D::Fun
    B::Fun
    D::Fun
    nBVal=2
    nBVal=24
    nDVal=8
    B::Fun
    nBVal=12

解题
分析输出

复制代码
    int main() { 
    	B * pb; D * pd; 
    	D d(4); d.Fun(); 
    			//D::Fun
    	pb = new B(2); pd = new D(8); 
    	pb -> Fun(); pd->Fun(); 
    	//B::Fun  	//D::Fun
    	pb->Print (); pd->Print (); 
    	//nBVal=2   //nBVal=24  nDVal=8
    	pb = & d; pb->Fun(); 
    			//B::Fun
    	pb->Print();   
    	//nBVal=12
    	return 0;
    }

以下是按照要求对原文进行了同义改写后的文本

补充的代码

复制代码
    #include <iostream>
    using namespace std;
    class B { 
    	private: 
    		int nBVal; 
    	public: 
    		void Print() 
    		{ cout << "nBVal="<< nBVal << endl; } 
    		void Fun() 
    		{cout << "B::Fun" << endl; } 
    		B ( int n ) { nBVal = n;} 
    };
    // 在此处补充你的代码
    class D:public B{
    	private:
    		int nDVal;
    	public:
    		void Fun(){
    			cout<<"D::Fun"<<endl;          
    		}
    		void Print()
    		{
    			B::Print();                      //直接调用父类的print函数 
    			cout<<"nDVal="<<nDVal<<endl;
    		}
    		D ( int n ) :nDVal(n),B(3*n){}     //构造函数——无法访问B的private,则直接调用b的构造函数 
    };
    //
    int main() { 
    	B * pb; D * pd; 
    	D d(4); d.Fun(); 
    	pb = new B(2); pd = new D(8);       
    	pb -> Fun(); pd->Fun();     //D::Fun       // B::Fun  D::Fun
    	pb->Print (); pd->Print (); // nBVal=2      // nBVal=24 nDVal=8
    
    
    	pb = & d; pb->Fun();  // B::Fun
    	pb->Print();        // nBVal=12
    	return 0;
    }

002:Fun和Do

描述
程序填空输出指定结果

复制代码
    #include <iostream> 
    using namespace std;
    class A { 
    	private: 
    	int nVal; 
    	public: 
    	void Fun() 
    	{ cout << "A::Fun" << endl; }; 
    	void Do() 
    	{ cout << "A::Do" << endl; } 
    }; 
    class B:public A { 
    	public: 
    	virtual void Do() 
    	{ cout << "B::Do" << endl;} 
    }; 
    class C:public B { 
    	public: 
    	void Do( ) 
    	{ cout <<"C::Do"<<endl; } 
    	void Fun() 
    	{ cout << "C::Fun" << endl; } 
    }; 
    void Call(
    // 在此处补充你的代码
    ) { 
    	p.Fun(); p.Do(); 
    } 
    int main() { 
    	C c; 
    	Call( c); 
    	return 0;
    }

输入

输出

复制代码
    A::Fun
    C::Do

分析输出

复制代码
    Call( c);

采用了A类中的方法Fun和C类中的方法Do。其中Fun是基于该基体结构定义的一个函数。由于B类继承自该结构体时实现了多态性,在此情况下其成员变量Do被定义为虚函数。通过调用B对象实例的方法即可实现对基体中Func及其多态形式Do的操作。

复制代码
    //原题
    #include <iostream> 
    using namespace std;
    class A {
    private:
    	int nVal;
    public:
    	void Fun()
    	{
    		cout << "A::Fun" << endl;
    	};
    	void Do()
    	{
    		cout << "A::Do" << endl;
    	}
    };
    class B :public A {
    public:
    	virtual void Do()
    	{
    		cout << "B::Do" << endl;
    	}
    };
    class C :public B {
    public:
    	void Do()
    	{
    		cout << "C::Do" << endl;
    	}
    	void Fun()
    	{
    		cout << "C::Fun" << endl;
    	}
    };
    void Call(B &p
    	// 在此处补充你的代码
    ) {
    	p.Fun(); p.Do();
    }
    int main() {
    	C c;
    	Call(c);
    	system("pause");
    	return 0;
    }

上述为引用对象调用多态,如下为指针对象调用多态

复制代码
    #include <iostream> 
    using namespace std;
    class A { 
    	private: 
    	int nVal; 
    	public: 
    	void Fun() 
    	{ cout << "A::Fun" << endl; };         //调用 
    	void Do() 
    	{ cout << "A::Do" << endl; } 
    }; 
    class B:public A { 
    	public: 
    	virtual void Do() 
    	{ cout << "B::Do" << endl;} 
    }; 
    class C:public B { 
    	public: 
    	void Do( ) 
    	{ cout <<"C::Do"<<endl; }        //调用 
    	void Fun() 
    	{ cout << "C::Fun" << endl; } 
    }; 
    void Call(
    // 在此处补充你的代码
    B *p          //B引用 
    // 
    ) { 
    	p->Fun(); p->Do();     //A的fun,c的do 
    } 
    int main() { 
    	B *b=new C();       //B* 类指向 C类动态对象
    	Call( b);           //A::Fun   
    						//C::Do  
    	return 0;
    }

003:这是什么鬼delete

描述
程序填空输出指定结果

复制代码
    #include <iostream> 
    using namespace std;
    class A 
    { 
    public:
    	A() { }
    // 在此处补充你的代码
    }; 
    class B:public A { 
    	public: 
    	~B() { cout << "destructor B" << endl; } 
    }; 
    int main() 
    { 
    	A * pa; 
    	pa = new B; 
    	delete pa; 
    	return 0;
    }

输入

输出

复制代码
    destructor B
    destructor A

分析输出
在执行B对象的析构造过程中,在随后将执行A对象的析构造步骤中进行操作,在确保程序逻辑正确性的前提下,在编译阶段需要对基类A增加一个虚解析构造方法以满足多态性需求,在这种情况下,在运行时若对包含多个引用层次的对象进行解析构造操作时,在最内层的对象实例被解析构造之前需要依次执行外部引用所指向的对象实例的具体解析构造过程

复制代码
    #include <iostream> 
    using namespace std;
    class A 
    { 
    public:
    	A() { }
    // 在此处补充你的代码
    virtual ~A(){
    	cout<<"destructor A"<<endl;
    }
    //
    }; 
    class B:public A { 
    	public: 
    	~B() { cout << "destructor B" << endl; }          //
    }; 
    int main() 
    { 
    	A * pa;      
    	pa = new B;              				
    	delete pa;               
    	return 0;
    }

004:怎么又是Fun和Do

描述
程序填空输出指定结果

复制代码
    #include <iostream>
    using namespace std;
    class A {
    	private:
    	int nVal;
    	public:
    	void Fun()
    	{ cout << "A::Fun" << endl; };
    	virtual void Do()
    	{ cout << "A::Do" << endl; }
    };
    class B:public A {
    	public:
    	virtual void Do()
    	{ cout << "B::Do" << endl;}
    };
    class C:public B {
    	public:
    	void Do( )
    	{ cout <<"C::Do"<<endl; }
    	void Fun()
    	{ cout << "C::Fun" << endl; }
    };
    void Call(
    // 在此处补充你的代码
    ) {
    	p->Fun(); p->Do();
    }
    int main() {
    	Call( new A());
    	Call( new C());
    	return 0;
    }

输入

输出

复制代码
    A::Fun
    A::Do
    A::Fun
    C::Do

分析输出
由于A类的do方法是虚方法,则当调用new A()时会必然触发A类的方法。
类似地,在调用new C()时会触发C类的方法。
如果一个方法不是虚方法,则不会产生多态性效果;因此不会有多态性,并且只会被继承自父级或子级类型的一种情况所影响。
这表明传入的对象是B类实例,则该实例只会被继承自父级或子级类型的一种情况所影响;该实例对应的指针类型应定义为B*类型变量即可实现相应的功能操作。

复制代码
    #include <iostream>
    using namespace std;
    class A {
    	private:
    	int nVal;
    	public:
    	void Fun()
    	{ cout << "A::Fun" << endl; };
    	virtual void Do()
    	{ cout << "A::Do" << endl; }
    };
    class B:public A {
    	public:
    	virtual void Do()
    	{ cout << "B::Do" << endl;}
    };
    class C:public B {
    	public:
    	void Do( )
    	{ cout <<"C::Do"<<endl; }
    	void Fun()
    	{ cout << "C::Fun" << endl; }
    };
    void Call(
    // 在此处补充你的代码
    A*p 
    // 
    ) {
    	p->Fun(); p->Do();
    }
    int main() {
    	Call( new A());      
    	Call( new C());
    	return 0;
    }

全部评论 (0)

还没有任何评论哟~