`
为心中梦想挥剑的那一刹那
  • 浏览: 7416 次
  • 性别: 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;
}

 

 

 

 

 

分享到:
评论

相关推荐

    C++程序设计谭浩强版

    ### C++程序设计谭浩强版 #### 一、引言 ...通过上述对《C++程序设计谭浩强版》各章节内容的梳理,我们可以看出这本书覆盖了C++编程从基础知识到高级特性的各个方面,非常适合初学者系统学习C++编程。

    C++程序设计谭浩强100%完整·清华大学

    ### 谭浩强《C++程序设计》内容概览 #### 第1篇 基本知识 第1章 C++的初步知识 - 1.1 从C到C++:介绍了C++语言的发展历程,如何从C语言演化而来。 - 1.2 最简单的C++程序:展示了最基本的C++程序结构。 - 1.3 C++...

    C++程序设计谭浩强版本的课件

    谭浩强版《C++程序设计》课件是对教材内容的一种详细梳理与总结,它覆盖了从C++的基础语法到面向对象编程的核心概念。下面将根据课件的目录,对各章节涉及的关键知识点进行详细的解析。 #### 第1篇 基本知识 **第1...

    C++程序设计谭浩强100%完整·清华大学.pdf

    通过以上章节的知识点梳理,我们可以看出《C++程序设计谭浩强100%完整·清华大学》这本书系统全面地覆盖了C++语言的基础知识、面向过程编程以及面向对象编程的核心概念和技术。对于初学者来说,这是一本非常适合入门...

    《谭浩强C++程序设计》书本笔记自己整理--2016查询参考

    以上是《谭浩强C++程序设计》第二章中关于数据类型和表达式的详细知识点梳理,涵盖了整型常量、浮点数、字符常量、符号常量、变量定义及初始化、算术运算符等多个方面。通过这些知识点的学习,读者可以更好地理解C++...

    谭浩强c语言程序设计

    ### 谭浩强C语言程序设计知识点梳理 #### C语言概述 - **发展过程**:C语言由Dennis Ritchie于1972年在贝尔实验室开发完成,最初是为了移植Unix操作系统而设计的。 - **当代最优秀的程序设计语言**:C语言因其简洁...

    C语言程序设计 谭浩强 学习笔记 word doc

    ### C语言程序设计知识点梳理 #### 一、C语言概述 **1.1 C程序结构特点** - **函数**: C程序的基本单位是函数。每个函数都有自己的功能,并且可以独立编译。 - **函数首部**: 包括函数类型、函数名以及参数列表...

    C++程序设计

    通过上述知识点的梳理,我们可以看到谭浩强老师编著的《C++程序设计》这本书内容丰富,覆盖了C++语言的基础知识、面向过程的程序设计、面向对象的程序设计等多个方面,适合初学者系统学习C++语言。

    谭浩强C程序设计课件

    《谭浩强C程序设计课件》是一套全面讲解C语言编程基础的教育资源,主要针对第三版的内容进行了详细的梳理和解读。这套课件涵盖了C语言的14个关键章节,旨在帮助初学者深入理解C语言的基本概念、语法结构以及编程技巧...

    谭浩强c语言程序设计.doc

    ### C语言程序设计知识点梳理 #### 一、C语言概述 - **发展过程**:C语言起源于20世纪70年代初期,由贝尔实验室的丹尼斯·里奇基于B语言设计并实现。最初用于UNIX操作系统,后来因其高效性和灵活性而广泛应用于...

    c程序设计基础

    ### C程序设计基础知识点梳理 #### 一、C语言简介 - **定义**: C语言是一种通用的、过程式的计算机程序设计语言,具有高效、灵活的特点。 - **地位**: 国际上最著名的高级程序设计语言之一,使用范围广泛。 - **...

    谭浩强C语言讲义(pdf版本,很好的入门C语言书)

    ### 谭浩强C语言讲义知识点梳理 #### 一、C语言概述 - **C语言的发展历程:** - C语言最初由Dennis Ritchie于1972年在贝尔实验室为Unix操作系统设计。 - 随后,由于其简洁、高效以及能够直接操作硬件等特点,在...

    谭浩强c语言学习教程

    - **面向对象的程序设计语言**:虽然C语言本身不支持面向对象编程,但其衍生的C++语言支持此类编程范式。 - **C和C++的区别**:C++是基于C语言扩展而成的一种面向对象的编程语言,增加了类、对象等概念。 - **简单的...

    C语言教程讲义(谭浩强)--免费

    - **当代最优秀的程序设计语言**:C语言因其简洁、灵活和强大,被广泛认为是学习编程的基础。它不仅适用于系统级编程(如操作系统和嵌入式系统),也用于应用软件开发。 - **C语言版本**:C语言经历了多个版本的发展...

Global site tag (gtag.js) - Google Analytics