`
为心中梦想挥剑的那一刹那
  • 浏览: 6866 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

c++程序设计梳理(谭浩强)10章

阅读更多

 大半夜的还不困,再来写一章。傍晚算了下,发现这个月所要的开支似乎相当大,所以给女朋友打了个电话,说这个1111可能买不了东西给她了。我知道,她是那种不吵不闹不公主之人,结果当然是接受的。后来自己又上网看了看自己想买的东西,然后发现似乎都不在我当下所承受的范围之内,并且也都没那么想买,着急卖,故今年就作罢吧。说实话想把《编程之美》和《essential C++》收了的,但是这两本书双11并不打折,外加我现在一堆书要看,硬是收了,肯定也都是先放在那里,在这缺钱的当口,实属不明智的选择,所以今年1111全部“按兵不动”。
 刚才看技术博客,有个介绍各大语言的IDE对比的,从中发现了Code::Blocks这个c++的IDE。小弟经验浅薄,以前还真没听过,更别提用过。后来下下来体验了下,我觉得在linux下面进行开发的IDE,这个是个不错的选择,我今天在这记录下来,以便以后能翻查的到。
 现在我来总结运算符重载这一章,第10章。这个运算符重载,算是c++开发领域相当之重要的特性了。能从新定义原先人们所熟知的操作符,例如+、-、/、*等等,所以在类的定义过程中,是非常关键的。在java中,重载Object所有类的基类中的方法equal来进行相等的判断,在c++中我们可以重新定义==这个符号来进行判断。java中并没有其他的符号重载的功能。我觉得在这一点上面,c++是做的非常灵活的,可控性完完全全的交给了开发者,让我们开发人能随心所欲的进行开发。当然缺点也是显而易见的,就是如果一不小心,出错的可能性加大,并且在项目庞大了之后,这个多出来的灵活功能会加大我们的维护精力,有时候会变得非常繁琐。有利必有弊,鱼和熊掌不可兼得,就是这个道理吧!
Chapter10
->运算符重载
1、运算符重载的基本代码:

class Complex{
public:
	Complex():real(0),imag(0){}
	Complex(double , double );
	void display();
	Complex operator+(Complex &c2);//此处就是运算符重载,具体的还可以有下面的几种方式
	friend Complex operator+(int, Complex&);//重载为友元函数模式
	friend Complex operator+(Complex&, int);
	//friend Complex operator+(Complex &, Complex &);//如果不是友元函数,在这个VS下面会报错,说是参数太多
	
private:
	double real;
	double imag;
};
Complex::Complex(double r, double i){
	this->imag = i;
	this->real = r;
}
void Complex::display(){
	cout << "(" << this->real << "," << this->imag << "i)" << endl;
}
Complex Complex::operator+(Complex &c2){//成员函数
	Complex c;
	c.real = this->real + c2.real;
	c.imag = this->imag + c2.imag;
	return c;
}
Complex operator+(int a, Complex &c){//友元函数
	return Complex(a + c.real, c.imag);
}
Complex operator+(Complex &a, int b){//友元函数
	return Complex(a.real+b,a.imag);
}

 

2、在这里我可以给出这个问题的答案了:c++的一个空类中,默认有哪些成员函数?
默认构造函数、析构函数、复制构造函数、复制赋值操作符(=)。(C++11还有转移构造函数和转移赋值操作符)
p.s:这个问题其实挺重要的,各大公司为了考察对c++的掌握的熟练程度,经常会出这种问题来考察!


3、一般,双目的运算符重载成友元函数,单目运算符重载成成员函数。但是>>、<<这两个输入输出流运算符只能重载成友元函数。原因我自己实践中体会到是这样的:因为成员函数只能带有一个形参,左侧的运算数据是本类,但是输入输出流的运算符要重载的话,必须要带有两个参数,一个是ostream&或者istream&,另外一个是我们要输入输出的对象,所以这种情况下只能重载成友元函数。下面是输入输出流重载的代码,>>运算符的重载其实功效和java中的重载toString方法是一样的,很有必要写一写!(java的Object类的toString方法重载,是经常发生的)

 

 

/*
header_file.h文件
*/
#include<iostream>
using namespace std;//这个标准命名空间中有输入输出的对象ostream与istream,必须要加入,否则下面的<<运算符重载声明会找不到这两个对象!
class Complex{
public:
	Complex():real(0),imag(0){}
	Complex(double , double );
	void display();
	friend ostream& operator << (ostream&,Complex&);//输出运算符重载
	friend istream& operator >> (istream&, Complex&);//输入运算符重载
	Complex operator+(Complex &c2);
	friend Complex operator+(int, Complex&);
	friend Complex operator+(Complex&, int);
	//friend Complex operator+(Complex &, Complex &);
	
private:
	double real;
	double imag;
};
/*
header_file.cpp文件
*/
#include "header_file.h"
#include<iostream>
Complex::Complex(double r, double i){
	this->imag = i;
	this->real = r;
}
void Complex::display(){
	cout << "(" << this->real << "," << this->imag << "i)" << endl;
}
Complex Complex::operator+(Complex &c2){
	Complex c;
	c.real = this->real + c2.real;
	c.imag = this->imag + c2.imag;
	return c;
}
Complex operator+(int a, Complex &c){
	return Complex(a + c.real, c.imag);
}
Complex operator+(Complex &a, int b){
	return Complex(a.real+b,a.imag);
}
ostream& operator << (ostream& out,Complex& c1){//输出实现
	out << "(" << c1.real <<","<<c1.imag<<"i)";
	return out;
}
istream& operator >> (istream& in, Complex& c){//输入实现
	in >> c.real >> c.imag;
	return in;
}
/*
主文件
*/
#include "header_file.h"
#include<iostream>
int main(){
	Complex c1(2,3), c2(4,5);
	c1 = c2+4;
//	c1.display();
	cin >> c1;
	cout << c1 << endl;;
	return 0;
}

 

 

 

4、不同类型数据之间的转换!(这个有点繁琐,其中包括很多类的默认操作,基本数据类型->对象类型、对象类型->基本数据类型、基本数据类型之间的转换)
(1)基本数据类型->对象类型:这个要用上类的转换构造函数
Complex(double r)
{
 this->real=r;
 this->imag=0;
}
这种情况下,除了我们可以显示的进行double类型到对象类型的转换,编译器也会默认进行double到对象的转换,例如
Complex c(2.4);//显示进行构造
c=2.5+c;//默认调用转换构造函数
在上面代码的第二行,2.5+c的过程中,如果我们没有进行运算符+的重载(左都变了右Complex的+),编译器会自动调用转换构造函数,代码如下 

 

/*
header_file.h文件
*/
#include<iostream>
using namespace std;//这个标准命名空间中有输入输出的对象ostream与istream,必须要加入,否则下面的<<运算符重载声明会找不到这两个对象!
class Complex{
public:
	Complex():real(0),imag(0){}
	Complex(double , double );
	Complex(double);
	void display();
	friend ostream& operator << (ostream&,Complex&);//输出运算符重载
	friend istream& operator >> (istream&, Complex&);//输入运算符重载
	//Complex operator+(Complex &c2);
	//friend Complex operator+(int, Complex&);
	//friend Complex operator+(Complex&, int);
	friend Complex operator+(Complex , Complex );
	
private:
	double real;
	double imag;
};
/*
header_file.cpp文件
*/
#include "header_file.h"
#include<iostream>
Complex::Complex(double r, double i){
	this->imag = i;
	this->real = r;
}
Complex::Complex(double r){
	this->real = r;
	this->imag = 0;
}
void Complex::display(){
	cout << "(" << this->real << "," << this->imag << "i)" << endl;
}
//Complex Complex::operator+(Complex &c2){
//	Complex c;
//	c.real = this->real + c2.real;
//	c.imag = this->imag + c2.imag;
//	return c;
//}
//Complex operator+(int a, Complex &c){
//	return Complex(a + c.real, c.imag);
//}
//Complex operator+(Complex &a, int b){
//	return Complex(a.real+b,a.imag);
//}
//这里要说明下:如果要想运用转换构造函数,来进行默认初始化,例如:4.2+c2,这里不能用引用,因为很简单,引用是地址传递,调用的时候并没有进行副本的复制拷贝,如果不用,调用时复制拷贝副本的时候,会默认调用转换构造函数,就是Complex(4.2)
Complex operator + (Complex c1, Complex c2){
	Complex c3;
	c3.real = c1.real + c2.real;
	c3.imag = c1.imag + c2.imag;
	return c3;
}
ostream& operator << (ostream& out,Complex& c1){
	out << "(" << c1.real <<","<<c1.imag<<"i)";
	return out;
}
istream& operator >> (istream& in, Complex& c){
	in >> c.real >> c.imag;
	return in;
}
/*
主文件
*/
#include "header_file.h"
#include<iostream>
int main(){
	Complex c1(2,3), c2(4,5);
	c1 = c2+4.3;
	Complex c = 4.2;//这里,同时调用了两个构造函数,首先是调用默认的复制构造函数(或者叫拷贝构造函数),其次Complex(4.2)(这个是在拷贝构造函数进行参数传递时调用的)
//	c1.display();
	cout << c << endl;;
	return 0;
}

 (2)对象类型->进本数据类型:这个主要用的是类型转换函数进行的转换。其实就是重载()这个运算符,但是这个运算符重载的过程比较特殊,并不用在最开始给出返回类型,其返回类型由函数名中类型名来确定的。而且这个运算符的重载必须要是成员函数,因为是要对此类的对象进行转换。(二义性的问题看注释!) 

 

/*
header_file.h文件
*/
#include<iostream>
using namespace std;//这个标准命名空间中有输入输出的对象ostream与istream,必须要加入,否则下面的<<运算符重载声明会找不到这两个对象!
class Complex{
public:
	Complex():real(0),imag(0){}
	Complex(double , double );
	Complex(double);
	void display();
	friend ostream& operator << (ostream&,Complex&);//输出运算符重载
	friend istream& operator >> (istream&, Complex&);//输入运算符重载
	//Complex operator+(Complex &c2);
	//friend Complex operator+(int, Complex&);
	//friend Complex operator+(Complex&, int);
	friend Complex operator+(Complex , Complex );
	operator double();//转换函数,返回类型为double
	
private:
	double real;
	double imag;
};
/*
header_file.cpp文件
*/
#include "header_file.h"
#include<iostream>
Complex::Complex(double r, double i){
	this->imag = i;
	this->real = r;
}
Complex::Complex(double r){
	this->real = r;
	this->imag = 0;
}
void Complex::display(){
	cout << "(" << this->real << "," << this->imag << "i)" << endl;
}
//Complex Complex::operator+(Complex &c2){
//	Complex c;
//	c.real = this->real + c2.real;
//	c.imag = this->imag + c2.imag;
//	return c;
//}
//Complex operator+(int a, Complex &c){
//	return Complex(a + c.real, c.imag);
//}
//Complex operator+(Complex &a, int b){
//	return Complex(a.real+b,a.imag);
//}
Complex operator + (Complex c1, Complex c2){
	Complex c3;
	c3.real = c1.real + c2.real;
	c3.imag = c1.imag + c2.imag;
	return c3;
}
ostream& operator << (ostream& out,Complex& c1){
	out << "(" << c1.real <<","<<c1.imag<<"i)";
	return out;
}
istream& operator >> (istream& in, Complex& c){
	in >> c.real >> c.imag;
	return in;
}
Complex::operator double(){//转换函数的实现!
	return this->real;
}
/*
主文件
*/
#include "header_file.h"
#include<iostream>
int main(){
	Complex c1(2,3), c2(4,5);
	//c1 = c2+4.3;//此时这里就出现二义性了,因为同时有转换构造函数和转换函数,编译器不知道具体是要将4.2通过转换构造函数转成对象,还是将对象通过转换函数转成基本数据类型double
	double d = c1;
	cout << d << endl;;
	return 0;
}

 

 

 

 

 

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics