C++之操作符重载

目录

 

静态成员

友员函数

操作符重载


静态成员

1.声明静态成员:在类中是声明静态变量,而不是定义

class Person{
    static int cnt;//表示cnt是属于Person类的,而不属于实例化对象的
    static int getcnt(void){
        return cnt;
    }
}

2.定义和初始化静态成员变量:需要在类外和main函数之外定义和初始化,在main函数之外定义是为了想要在对象实例化之前将静态成员变量定义和初始化完成

/* 定义和声明静态变量 */
int Person::cne = 0;//看起来是全局变量,但实际上是Person类中的静态成员变量

3.在静态函数中,不能够访问非静态成员变量

4.有两种方法调用成员变量

1)直接调用

int main()
{
    Person::getcnt();
}

2)通过对象来调用

int main()
{
    Person per
    per.getcnt();
}

demo

#include <iostream>
#include <string.h>
#include <unistd.h>


using namespace std;

class Person{
	char *name;
	int age;
	char *work;
	static int cnt;/*声明静态变量成员*/

public:

	static int getCount(){
		return cnt;
	}
	
	Person(){
		name = NULL;
		work = NULL;
		cnt++;
	}

	Person(char* name){
		/*开辟一个空间储存名字,但是子程序中的空间需要我们自己释放*/
		this->name = new char[strlen(name)+1];
		strcpy(this->name,name);//将参数名字放入开辟的空间之内

		this->work = NULL;//没有work这个参数,要赋值一个null给他,否则析构函数中会出现段错误
		cnt++;
	}

	Person(char* name, int age, char* work = "none"){
		cout<<"Person(char*, int)"<<endl;
		
		this->name = new char[strlen(name)+1];
		strcpy(this->name,name);
		
		this->work = new char[strlen(work)+1];
		strcpy(this->work,work);
		
		this->age = age;

		printfInfo();
		cnt++;
	}

	Person(Person &per){//拷贝函数
		cout<<"Person(Person &)"<<endl;
		
		this->name = new char[strlen(per.name)+1];
		strcpy(this->name,per.name);
		
		this->work = new char[strlen(per.work)+1];
		strcpy(this->work,per.work);
		
		this->age = per.age;
		cnt++;
	}

	~Person(){//析构函数,有助于在跳出程序(比如关闭文件、释放内存等)前释放资源。
		cout<<"~Person()"<<endl;
		if(this->name){
			cout<<"name ="<<name<<endl;
			delete this->name;
		}
		if(this->work){
			cout<<"work ="<<work<<endl;
			delete this->work;
		}
	}
	

	void printfInfo(){
		cout<<" name = "<<name<<" age = "<<age<<"work = "<<work<<endl;
	}
};

int Person ::cnt = 0;//定义和初始化静态变量成员

int main(int argc, char** argv)
{
	Person per;
	Person per1;
	Person per2;
	Person per3;

	Person per4[100];

	cout<<"Person cnt = "<<Person::getCount()<<endl;

	return 0;

}
zhaohaip@ubuntu:~/c++_project/06_static$ ./project 
Person cnt = 104

友员函数

声明友员函数

friend 类名 函数名()

friend Point add(Point &p1, Point &p2);

demo

#include <iostream>

using namespace std;

class Point{
private:
	int x;
	int y;

public:
	Point(){}

	Point(int x, int y):x(x), y(y){}

	void printInfo()
	{
		cout<<"("<<x<<","<<y<<")"<<endl;
	}

	friend Point add(Point &p1, Point &p2);//将该成员函数设置为友员函数
};

Point add(Point &p1, Point &p2)
{
	Point n;
	n.x = p1.x+p2.x;
	n.y = p1.y+p2.y;
	n.printInfo();
}


int main(int argc, char **argv)
{
	Point p1(1,2);
	Point p2(2,3);

	add(p1,p2);
}
book@100ask:~/c++_project/07_friend$ g++ main2.cpp 
book@100ask:~/c++_project/07_friend$ ./a.out 
(3,5)

操作符重载

1.运算符重载的定义是什么?

   改变运算符的运算过程叫运算符重载。

2.为什么说运算符重载也体现了多态性?

   首先,各种数据类型的数据进行“ + ”、“ - ”、“ * ”、“ / ”等运算的区别在于运算过程不同,不同的数据类型对应不同的运算过程,    这就恰恰体现了运算过程的多态性,也就是体现出了多态性。

3.运算符重载分为哪几种?

   运算符重载分为普通运算符重载(“ + ”、“ - ”、“ * ”、“ / ”等)、前置运算符重载("++"、"--")、后置运算符重载("++"、"--")、插入运算符重载(">>")、提取运算符重载("<<")

4.重载运算符的方式有哪几种?

   (1)令运算符重载函数作为类的成员函数

   (2)令运算符重载函数作为类的友员函数

当我们需要进行相加相减时,可直接

int a;
int b;
int c = a+b;

而a+b其实是一个函数来的。但是在point类中,是不允许这样相加减的。所以需要操作符重载。

定义重载操作符(+)函数

Point operator+(Point &p1, Point &p2)
//类名 operator运算符(参数)

demo

#include <iostream>

using namespace std;

class Point{
private:
	int x;
	int y;

public:
	Point(){}

	Point(int x, int y):x(x), y(y){}

	void printInfo()
	{
		cout<<"("<<x<<","<<y<<")"<<endl;
	}

	friend Point add(Point &p1, Point &p2);
	friend Point operator+(Point &p1, Point &p2);
};

Point add(Point &p1, Point &p2)
{
	Point n;
	n.x = p1.x+p2.x;
	n.y = p1.y+p2.y;
	n.printInfo();
}

Point operator+(Point &p1, Point &p2)
{
	cout<<"Point operator+(Point &p1, Point &p2)"<<endl;
	Point n;
	n.x = p1.x+p2.x;
	n.y = p1.y+p2.y;
	return n;
}

int main(int argc, char **argv)
{
	Point p1(1,2);
	Point p2(2,3);

	//p1+p2是不可以的,在point类中需要运用操作符重载进行相加减

	add(p1,p2);
	cout<<"****************"<<endl;

	Point sum = p1+p2;
	sum.printInfo();
}

运行结果

zhaohaip@ubuntu:~/c++_project/08_operator$ ./project                             
(3,5)
****************
Point operator+(Point &p1, Point &p2)
(3,5)

通过代码实现p++与++p

注意:由于p++与++p的操作符重载的函数名是一样的,而我们需要区分他们。这等同于函数重载,通过函数参数的不同来应用相同的函数名实现不同的功能。p++的操作符重载会比++p的操作符重载多一个参数,这个参数不会使用,只是用来区分。

demo

#include <iostream>

using namespace std;

class Point{
private:
	int x;
	int y;

public:
	Point(){
		cout<<"Point()"<<endl;
	}

	Point(int x, int y):x(x), y(y){
		cout<<"Point(int x, int y)"<<endl;
	}

	~Point(){
		cout<<"~Point()"<<endl;
	}

	Point(Point &p){
		cout<<"Point(Point &p)"<<endl;
		x = p.x;
		y = p.y;
	}

	void printInfo()
	{
		cout<<"("<<x<<","<<y<<")"<<endl;
	}

	friend Point operator++(Point &p);
	friend Point operator++(Point &p,int a);
};

/* 实现p1++	*/

Point operator++(Point &p,int a)
{
	cout<<"p++"<<endl;
	
	Point n;
	n = p;
	p.x += 1;
	p.y += 1;

	return n;	
}

/* 实现++p	*/
Point operator++(Point &p)
{
	cout<<"++p"<<endl;

	p.x += 1;
	p.y += 1;

	return p;
}

int main(int argc, char **argv)
{
	Point p1(1,2);

	cout<<"begin"<<endl;
	p1++;

	cout<<"******************"<<endl;

	++p1;
	cout<<"end"<<endl;

}
zhaohaip@ubuntu:~/c++_project/08_operator$ ./project 
Point(int x, int y)
begin
p++
Point()
~Point()
******************
++p
Point(Point &p)
~Point()
end
~Point()

这样的代码是有缺点的,通过运行结果我们可以知道,在执行++p的时候,无端的调用了Point(Point &p)引用拷贝,而且多引用了一次析构函数,这大大的影响了我们的效率,可以改变++p操作符重载函数的返回类型,让其返回&引用的类型,会不一样

/* 实现++p	*/
Point &operator++(Point &p)
{
	cout<<"++p"<<endl;

	p.x += 1;
	p.y += 1;

	return p;
}
zhaohaip@ubuntu:~/c++_project/08_operator$ ./project 
Point(int x, int y)
begin
p++
Point()
~Point()
******************
++p
end
~Point()
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值