c++的重载重载运算(一)

重载运算符是具有特殊名字的函数,它们的关键字operator和其后要定的运算符号共同组成。现在就让我们了解一下c++的重载运算吧。

一.输入和输出运算符

class Person {
	friend std::ostream& operator<<(std::ostream& os, const Person& person);
public:
	Person() {};
	Person(int he, int we, const std::string& names) :height(he), weight(we), name(new std::string(names)) {};
	~Person() { delete name; };
private:
	int height;
	int weight;
	std::string *name;
};
std::ostream& operator<<(std::ostream& os, const Person& person) {
	os << person.height << " " << person.weight << " " << person.name->c_str();

	return os;
}
int main(void)
{
	Person person(170, 120, "Jay");
	std::cout << person;

	return 0;
}

operator<<的第一个形参必须是ostream类。为什么呢?因为输出流是个动态过程,IO操作是不能copy的。第二个形参是const引用的类类型。为什么呢?因为打印类的状态,我们要求它是不能改变的,而且打印的是对象本身,而不是对象的副本。所以返回ostream的引用。

class Person {
	friend std::istream& operator>>(std::istream& is, Person& person);
private:
	int height;
	int weight;
};
std::istream& operator>>(std::istream& is, Person& person) {
	is >> person.height >> person.weight;
	
	return is;
}
int main(void)
{
	Person person;
	std::cin >> person;

	return 0;
}

operator>>的第一个参数必须是istream类型,而且必须是非const引用类型。为什么呢?因为输入流是个动态过程,IO操作是不能copy。第二个参数是非const引用的类类型。为什么呢?因为类的属性或者状态是在改变的

二.算数运算符

class Person {
	friend const Person operator+(const Person& person1, const Person& person2);
	friend const Person operator-(const Person& person1, const Person& person2);
public:
	Person() {};
	Person(int he, int we) :height(he), weight(we) {};
private:
	int height;
	int weight;
};
const Person operator+(const Person& person1, const Person& person2) {
	return Person(person1.height + person2.height, person2.weight + person2.weight);
}
const Person operator-(const Person& person1, const Person& person2) {
	return Person(person1.height - person2.height, person2.weight - person2.weight);
}
int main(void)
{
	Person person1(170, 120);
	Person person2(175, 100);
	Person person3 = person1 + person2;
	Person person4 = person1 - person2;

	return 0;
}

重载的算术运算符的形参都是const的类类型引用,为什么呢?因为一般不需要改变对象的状态,所以形参都是常量的引用。

三.关系运算符

class Person {
	friend bool operator==(const Person& person1, const Person& person2);
	friend bool operator> (const Person& person1, const Person& person2);
	friend bool operator< (const Person& peraon1, const Person& person2);
	friend bool operator!=(const Person& person1, const Person& person2);
public:
	Person(int he, int we) :height(he), weight(we) {};
private:
	int height;
	int weight;
};
bool operator==(const Person& person1, const Person& person2) {
	return person1.height == person2.height && person2.weight == person2.weight;
}
bool operator> (const Person& person1, const Person& person2) {
	return person1.height > person2.height && person1.weight > person2.weight;
}
bool operator< (const Person& person1, const Person& person2) {
	return person1.height < person2.height && person1.weight < person2.weight;
}
bool operator!=(const Person& person1, const Person& person2) {
	return !(person1 == person2);
}
int main(void)
{
	Person person1(170, 100);
	Person person2(165, 120);
	if (person1 == person2)
		std::cout << "operator==";
	if (person1 != person2)
		std::cout << "operator!=";
	if (person1 > person2)
		std::cout << "operator>";
	if (person1 < person2)
		std::cout << "operator>";
	
	return 0;
}

四.赋值运算符

class Person {
public:
	Person(int he_=0, int we_=0) :height(he_), weight(we_) {};
	Person& operator=(const Person& rhs) {
		if (this == &rhs)
			return *this;
		else {
			height = rhs.height;
			weight = rhs.weight;
		}
		
		return *this;
	}
	void print() {
		std::cout << "height:" << height << "      " << "weight:" << weight;
	}

private:
	int height;
	int weight;
};

int main(void)
{
	Person person(170, 100);
	Person person_;
	person_ = person;
	person.print();
	
	return 0;
}

赋值运算符往往要定义为类的成员函数。

五.下标运算符

class Person {
public:
	Person(std::string* na_ = 0) :name(na_) {};
	std::string& operator[](std::size_t n) {
		return name[n];
	}
	/*const std::string& operator[](std::size_t n) {
		return name[n];
	}*/
	void print() {
		std::cout << name->c_str();
	}
private:
	std::string* name;
};

int main(void)
{
	std::string name = "Jay";
	Person person(&name);
	person.print();
	
	return 0;
}

下表运算符有两个版本:一个返回普通引用。另一个是类的常量成员并返回常量引用。

六.递增递减运算符

class Person {
public:
	Person(int he_) :height(he_) {};
	Person& operator++() {
		height += 1;
		return *this;
	}
	Person& operator--() {
		height -= 1;
		return *this;
	}
	Person operator++(int) {
		Person rhs = *this;
		height += 1;
		return rhs;
	}
	Person operator--(int) {
		Person rhs = *this;
		height -= 1;
		return *this;
	}
	void print() {
		std::cout << height << "\n";
	}
private:
	int height;
};

int main(void)
{
	Person person(170);
	++person; person.print();
	person++; person.print();
	--person; person.print();
	person--; person.print();

	return 0;
}

定义递增和递减运算符的类应该同时定义前置版本和后置版本。后置版本的int形参只具有区分作用,所以无须为其命名

七.成员访问运算符

class Person {
public:
	Person(std::string* na_ = 0) :name(na_) {};
	std::string& operator*() {
		return *name;
	}
	std::string* operator->() {
		return name;
	}
	void print() {
		std::cout << name->c_str();
	}
private:
	std::string* name;
};
int main(void)
{
	std::string name = "Jay";
	Person person(&name);
	person.print();

	return 0;
}

为什么operator*()的返回值是std::string& 呢? 因为std::string* 意为其指针指向的对象是可以改变的,所以不能是std::string。

八.函数调用运算符

class Person {
public:
	Person(const std::string& na = std::string()) :name(new std::string(na)) {};
	~Person() { delete name; };
	void operator()(const std::string& name) {
		std::cout << name.c_str();
	}
private:
	std::string* name;
};
int main(void)
{
	Person person;
	person("Jay");

	return 0;
}

我们可以像使用函数一样使用该对象(函数对象),此时的类也能存储状态。

九.类型转换运算符

class Tree {
public:
	Tree(const std::string& str=std::string()) :name(new std::string(str)) {};
	~Tree() { delete name; };
	operator std::string() const {      //operator type() const{};
		return *name;
	}

private:
	std::string* name;
};

int main(void)
{
	std::string name = "Jay";
	Tree tree(name);
	std::cout << tree.operator std::string().c_str();
}

类型转换运算符可以面向任意的类型进行定义,只要该类型能作为函数的返回类型。类型转换运算符必须类的成员函数,不能声明返回类型,参数列表也必须为空,通常应该是const,因为类型转换运算符只起转换作用,而不改变类的数据成员变量。

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值