1. 程式人生 > >學習c++多型的幾個小例子

學習c++多型的幾個小例子

//reference: http://blog.csdn.net/hackbuteer1/article/details/7475622

#include<iostream> 
#include<string>
#include <vector>

using namespace std;  

class Time
{
public:
	int hour;
	int minute;
	int second;

protected:
private:
};

Time t1={14,56,30}; 

class A  
{
	public:  
		void foo()  
		{
			printf("A foo()\n");  
		}

		virtual void fun()  
		{
			printf("A virtual fun()\n");  
		}
};

class B : public A  
{
	public:  
		void foo()  
		{
			printf("B foo()\n");  
		}

		void fun()  
		{
			printf("B virtual fun()\n");  
		}
};

class Base  
{
	public:  
		virtual void f(float x)  
		{
			cout<<"Base::f(float)"<< x <<endl; 
		}

		void g(float x)  
		{
			cout<<"Base::g(float)"<< x <<endl;  
		}

		void h(float x)  
		{  
			cout<<"Base::h(float)"<< x <<endl;  
		}  
};

class Derived : public Base  
{
public:
	//Derived::f(float)覆蓋了Base::f(float)。
	virtual void f(float x)  
	{
		cout<<"Derived::f(float)"<< x <<endl;   //多型、覆蓋
	}

	//Derived::g(int)隱藏了Base::g(float),而不是過載
	void g(int x)  
	{
		cout<<"Derived::g(int)"<< x <<endl;     //隱藏,不是過載
	}

	//Derived::h(float)隱藏了Base::h(float),而不是覆蓋。
	void h(float x)  
	{
		cout<<"Derived::h(float)"<< x <<endl;   //隱藏 
	}
};

class Shape//形狀
{
public:
	virtual void DrawSelf()//繪製自己
	{
		cout << "我是一個什麼也繪不出的圖形" << endl;
	}
};

class Polygo:public Shape//多邊形
{
	public:
		virtual void DrawSelf()
		{
			cout << "連線各頂點" << endl;
		}
};

class Circ:public Shape//圓
{
public:
	virtual void DrawSelf()   //繪製自己
	{
		cout << "以圓心和半徑為依據畫弧" << endl;
	}
};

void OutputShape( Shape arg)//專門負責呼叫形狀的繪製自己的函式
{
	arg.DrawSelf();
}

void OutputShape1( Shape& arg)//專門負責呼叫形狀的繪製自己的函式

{
	arg.DrawSelf();
}

void displayShape(Shape *arg)
{
	arg->DrawSelf();
}

int my_add(int a, int b)
{
	return a + b;
}

int my_add(int a, std::string b)
{
	return a + atoi(b.c_str());
}

//巨集多型, 帶變數的巨集可以實現一種初級形式的靜態多型
#define ADD(A, B) ((A) + (B))

class Vehicle
{
public:
	virtual void run() const = 0;	//純虛擬函式,該類為抽象類,不能例項化物件
};

// 派生於Vehicle的具體類Car
class Car: public Vehicle
{
public:
	virtual void run() const
	{
		std::cout << "run a car\n";
	}
};

class Airplane: public Vehicle
{
public:
	virtual void run() const
	{
		std::cout << "run a airplane\n";
	}

	void add_oil() const
	{
		std::cout << "add oil to airplane\n";
	}
}; 

class Airship: public Vehicle
{
public:
	virtual void run() const
	{
		std::cout << "run a airship\n";
	}

	void add_oil() const
	{
		std::cout << "add oil to airship\n";
	}
};

void run_vehicle(const Vehicle* vehicle)
{
	vehicle->run();            // 根據vehicle的具體型別呼叫對應的run()
}

// run異質vehicles集合
void run_vehicles(const std::vector<Vehicle*>&vehicles)
{
	for (int i = 0; i < vehicles.size(); i++)
	{
		vehicles[i]->run();
	}
}

// 為某種特定的aircrafts同質物件集合進行“空中加油”
template <typename Aircraft>
void add_oil_to_aircrafts_in_the_sky(const std::vector<Aircraft>& aircrafts)
{
	for (unsigned int i = 0; i < aircrafts.size(); i++)
	{
		aircrafts[i].add_oil();
	}
};

//靜態多型
class SCar
{
	public:
		void run() const
		{
			std::cout << "run a SCar\n";
		}
};

class SAirplane
{
public:
	void run() const
	{
		std::cout << "run a SAirplane\n";
	}
};

// 通過引用而run任何vehicle
template <typename Vehicle>
void run_svehicle(const Vehicle& vehicle)
{
	vehicle.run();            // 根據vehicle的具體型別呼叫對應的run()
}

// run同質vehicles集合
template <typename Vehicle>
void run_svehicles(const std::vector<Vehicle>& vehicles)
{
	for (unsigned int i = 0; i < vehicles.size(); i++)
	{
		vehicles[i].run();
	}
}

int main()
{
	 //A a;  
	 //B b;  

	 //a.foo();
	 //a.fun();
	 //b.foo();
	 //b.fun();

	 //A *p = &a;  
	 //p->foo();
	 //p->fun();

	 //p = &b;  
	 //p->foo();
	 //p->fun();

	 //B *ptr = (B *)&a;  
	 //ptr->foo();  
	 //ptr->fun();
	 //cout<<endl;

	 //Derived d;  
	 //Base *pb = &d;  
	 //Derived *pd = &d;  

	 //pb->f(3.14f);   //Derived, 多型
	 //pd->f(3.14f);   //Derived

	 //pb->g(3.14f);   //Base
	 //pd->g(3.14f);	  //Derived

	 //pb->h(3.14f);   //Base
	 //pd->h(3.14f);	  //Derived

	Polygo shape1;
	Circ shape2;

	shape1.DrawSelf();
	shape2.DrawSelf();

	displayShape(&shape1);
	displayShape(&shape2);
	
	OutputShape1(shape1);
	OutputShape1(shape2);

	//向上轉型中的子型別資訊丟失
	OutputShape(shape1);
	OutputShape(shape2);

	int i = my_add(1, 2);                // 兩個整數相加
	int s = my_add(1, "2");              // 一個整數和一個字串相加
	std::cout << "i = " << i << "\n";
	std::cout << "s = " << s << "\n";

	int i1(1), i2(2);
	string s1("Hello, "), s2("world!");
	int is = ADD(i1, i2);
	string ss = ADD(s1, s2);
	cout<<"is = "<<is<<endl;
	cout<<"ss = "<<ss<<endl;
	cout<<ADD(3, 9.3434)<<endl;
	cout<<ADD(2, 3434.f)<<endl;
	cout<<ADD("sdf", 8)<<endl;
	cout<<ADD("sdf", '2')<<endl;
	cout<<ADD('A', 32)<<endl;
	cout<<ADD('A', '0')<<endl;

	Car car;
	Airplane airplane;
	run_vehicle(&car);         // 呼叫Car::run()
	run_vehicle(&airplane);    // 呼叫Airplane::run()

	std::vector<Vehicle*>v;
	v.push_back(&car);
	v.push_back(&airplane);
	run_vehicles(v);
	cout<<endl;

	Car car11, car12;
	Airplane airplane11, airplane12;
	Airship airship11, airship12;

	std::vector<Vehicle*> v1;                // 異質vehicles集合
	v1.push_back(&car11);
	v1.push_back(&airplane11);
	v1.push_back(&airship11);
	run_vehicles(v1);                        // run不同種類的vehicles

	std::vector<Airplane> vp;  
	vp.push_back(airplane11);
	vp.push_back(airplane12);
	add_oil_to_aircrafts_in_the_sky(vp);    // 為airplanes進行“空中加油”

	std::vector<Airship> vs1;
	vs1.push_back(airship11);
	vs1.push_back(airship12);
	add_oil_to_aircrafts_in_the_sky(vs1);    // 為airships進行“空中加油”
	cout<<endl;

	SCar scar;
	SAirplane sairplane;
	run_svehicle(scar);         // 呼叫Car::run()
	run_svehicle(sairplane);    // 呼叫Airplane::run()
	cout<<endl;

	SCar car1, car2, car3;
	SAirplane airplane1, airplane2,  airplane3;
	std::vector<SCar> vc; 
	vc.push_back(car1);
	vc.push_back(car2);
	vc.push_back(car3);
	//vc.push_back(airplane1);
	run_svehicles(vc);

	std::vector<SAirplane> vs; 
	vs.push_back(airplane1);
	vs.push_back(airplane2);
	vs.push_back(airplane3);
	run_svehicles(vs);

	return 0;
}