朝歌挽酒

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

重载与多态

一.运算符重载

定义:运算符重载是对已有运算符赋予多重含义,使同一个运算符作用于不同类型的数据时导致不同的行为。例如:
在这样一段程序中,我们对a,b进行加法运算,

 # include < iostream >
using namespace std;
class Counter
{public :
	Counter() {};
	Counter(int i) { count = i; }
	private :
	int count;
};
int main()
{
	Counter a(1),b(2),c;
	cout << "a=" << a<

会出现这样的错误


这时候就需要运算符重载

1.1

运算符重载的规则:(1)c++中的运算符大多可以重载,而且只能重载已有运算符。
(2)重载之后运算符优先级和结合性都不会改变。
(3)运算符重载是针对新类型数据的实际需要,对原有运算符进行适当的改造。
运算符重载为类的成员函数的语法形式:
返回类型 operater 运算符{形参表}
{
函数体
}
以非成员函数重载的语法与之相同,但有时访问涉及到私有成员,可以将函数声明为友元函数。例如:

 # include < iostream >
using namespace std;
class Counter
{public :
	Counter() {};
	Counter(int i) { count = i; }
	friend Counter operator+(const Counter & c1, const Counter & c2);
	friend ostream& operator<< (ostream & cout, Counter&c1);
	
private :
	int count;
};
Counter operator + (const Counter & c1, const Counter & c2)  {
	return Counter (c1.count+c2.count);
}

ostream& operator<< (ostream & cout, Counter&c1) {
	cout << c1.count;
	return cout;
}
int main()
{
	Counter a(1),b(2),c;
	cout << "a=" << a<

结果:

注意:当运算符重载为类的成员函数时,函数的参数比原来的操作个数少一个;重载为非成员函数时参数个数与原操作数相同

1.2运算符重载成员函数和非成员函数

以将单目运算符++重载为例,
成员函数:

  # include< iostream >
using namespace std;
class Complex {
public:
	Complex(double r = 0.0, double i = 0.0) :real(r), imag(i) {}
	 Complex operator++()const;
	 Complex operator++(int)const;
	void display() {
		cout<<"real:"<real;
	c.imag = this->imag;
	return c;
}
Complex Complex:: operator++( int)const{
	Complex c=*this;
	c.real++;
	c.imag++;	
	return c;
}
int main() {
	Complex c1(5, 4), c2, c3;
	cout << "c1="; 
	c1.display();
	c2 = ++c1;
	cout << "c2=" ; 
	c2.display();
	c3 = c1++;
	cout << "c3=" ; 
	c3.display();
	system("pause");
}

在本例中前置与后置最大的不同在于有无形参,其他的与普通的成员函数,没有什么区别只是++这个运算符能做用于不同的对象上,有了更广泛的多态特征。
非成员函数:
因访问私有成员,声明为友元函数

  # include< iostream >
using namespace std;
class Complex {
public:
	Complex(double r = 0.0, double i = 0.0) :real(r), imag(i) {}
	friend Complex operator++(Complex &c1);
	friend Complex operator++(Complex &c1,int);
	void display() {
		cout<<"real:"<

结果:

二.多态

定义:指同样的消息被不同类型对象接受时导致的不同行为。在实现时可以分为静态多态和动态多态。
静态多态:在编译过程中确定了同名操作的具体操作对象,例如重载。
动态多态:运行过程才动态的确定操作针对的对象,例如虚函数。

2.1虚函数

虚函数是动态绑定的基础。是非静态的成员函数。
语法:virtual 函数类型 函数名{形参表};

而运行多态需要满足三个条件:(1)满足赋值兼容规则。(2)声明虚函数。(3)用成员函数调用或者是通过指针或者引用来访问。
例:

  # include < iostream >
using namespace std;
class Mammal
{
public:
	Mammal() { cout << "constructors Mammal"<Speak();
}
int main()
{
	Dog d;
	fun(&d);;
	system("pause");
	return 0;
}


可见函数成员speak()声明为虚函数,覆盖了基类的虚函数如需访问基类使用指针,这样,能够对同一类族中的对象进行统一处理,抽象程度更高,更简洁,高效。

2.2虚析构函数

语法:virtual ~类名();
虚析构函数是为了彻底释放内存,防止内存泄露。例:

  # include < iostream >
using namespace std;
class BaseClass
{
public:
	virtual~BaseClass() {
		cout << "虚函数 ~BaseClass()" << endl;
	}
};

class DerivedClass : public BaseClass
{
public:
	virtual ~DerivedClass()	{
		cout << "虚函数 ~DerivedClass()" << endl;
	}
};

int main()
{
	BaseClass *p= new DerivedClass;	
	delete p;
	system("pause");
}

不设为虚析构函数:

设为虚析构函数:

posted on 2019-10-26 14:16  朝歌挽酒  阅读(111)  评论(0编辑  收藏  举报