C++ Primer Plus 第八章知识点(二)

C++ Primer Plus 第八章知识点简化

1. 缺省值

归纳点

  • 缺省值的使用;
#include <iostream>
using namespace std;

const int ArSize = 80;
char* left(const char * str, int n=1);    // 只用在该处写上默认值

int main(){	
	char sample[ArSize];
	cout << "Enter a string:\n";
	cin.get(sample, ArSize);
	char* ps = left(sample, 4);
	cout << ps << endl;
	delete[] ps;       // free old string
	ps = left(sample);
	cout << ps << endl;
	delete[] ps;       // free new string
	return 0;
}

char* left(const char* str, int n){
	if (n < 0)
		n = 0;
	char* p = new char[n + 1];
	int i;
	for (i = 0; i < n && str[i]; i++)
		p[i] = str[i];  // copy characters
	while (i <= n)
		p[i++] = '\0';  // set rest of string to '\0'
	return p;
}

输出:
Enter a string:
hello world
hell
h

笔记
 
 
 
 
 


注意点

  • 必须从右向左来添加缺省值;int fun(double a, float b, int c=0);
  • 函数定义与声明只用在声明处写上默认值,否则重定义(若没有声明就在定义处写上)。

 


2. 重载

归纳点

  • 重载的概念;
  • 重载的注意点;
    – 数据转换
    – const的问题

       函数重载即函数多态,使得能够使用多个同名的函数,他们之间怎么区分呢?靠的是形参,也就是形参数目以及类型,要是全相同就不能,例如void fun(int a, float b)double fun(int a, float b)这两者只有返回值类型不一样,形参全一样,这样程序报错。
 
       重载有时会将数据进行 强制转换,这种情况发生在唯一原型上。看下面的程序可知print(year, 10) 只和 void print(double, int)相匹配,若加上另一个函数 void print(float, int),那么此时就不是唯一原型了,程序报错。

#include<iostream>
#include<string>
using namespace std;

void print(int, int);
void print(string, int);

int main(){	
	double year = 100.1;
	print(year, 10);
	return 0;
}

void print(int a, int b) {
	cout << a << b << endl;
}
void print(string a, int b) {
	cout << a;
}

输出:
10010

笔记
 
 
 
 
 


       重载里面 void fun(const string a); 和 void fun(string a);可以同时存在,这时 const常量会给到前者,非const就会给到后者。那么此时就有问题了:

  • 若只有后者,现在我有一个const string a;,这时会报错吗?
    答案是不会,因为非const值是可以赋给const变量的;
     
  • 若只有前者,现在我有一个string a;,这时会报错吗?
    这时就会报错,非const值赋给const变量是合法的,反之则不行。

 


3. 模板

归纳点

  • 模板的概念;
  • 显示具体化
  • 显示实例化
  • 完全匹配和最佳匹配

       函数模板即泛型,假如有个函数是将两个int值交换,这时候要交换两个double值,且不损失地进行交换怎么办?这里说到的不损失就是不走刚才两个int交换的函数,因为强制转换会有损失,那就只能再重写一个double值交换的函数,具体操作就是复制刚才函数,将int改成double,是不是程序冗余费时还容易出错?这时候泛型起到作用。
 

#include<iostream>
using namespace std;

template <typename T>  // or template <class` T>
void Swap(T& a, T& b);

int main(){
	int i = 10;
	int j = 20;
	cout << "i, j = " << i << ", " << j << ".\n";
	cout << "Using compiler-generated int swapper:\n";
	Swap(i, j);			// generates void Swap(int&, int&)
	cout << "Now i, j = " << i << ", " << j << ".\n" << endl;

	double x = 24.5;
	double y = 81.7;
	cout << "x, y = " << x << ", " << y << ".\n";
	cout << "Using compiler-generated double swapper:\n";
	Swap(x, y);			// generates void Swap(double&, double&)
	cout << "Now x, y = " << x << ", " << y << ".\n";
	return 0;
}

template <typename T>		// 别忘了声明和定义都要加这么一句
void Swap(T &a, T &b){
	T temp = a;
	a = b;
	b = temp;
}

输出:
i, j = 10, 20.
Using compiler-generated int swapper:
Now i, j = 20, 10.

x, y = 24.5, 81.7.
Using compiler-generated double swapper:
Now x, y = 81.7, 24.5.

笔记
 
 
 
 
 


       上面简要介绍模板用法,但有个问题可以来思考下:刚才那个换数据类型由int --> double 用刚才模板即可,交换的话直接用个temp作为中间值来实现,但数据类型如果是结构体,交换的是其中的成员该怎么办,可以用刚才那个函数吗?显然不可以,但又是实现交换,和刚才一样功能,就这个struct是个特殊的,单独为struct写一个?有更快的办法吗?

       方法是有的,还是用模板,但需要 显示具体化,如下所示:

#include <iostream>
using namespace std;

struct job {
	char name[40];
	double salary;
	int floor;
};

template <typename T>
void Swap(T &a, T &b);
// explicit specialization
template <> void Swap<job>(job &j1, job &j2);	// or template <> void Swap(job &j1, job &j2); 
void Show(job &j);

int main() {
	cout.precision(2);
	cout.setf(ios::fixed, ios::floatfield);
	int i = 10, j = 20;
	cout << "i, j = " << i << ", " << j << ".\n";
	cout << "Using compiler-generated int swapper:\n";
	Swap(i, j);				// generates void Swap(int &, int &)
	cout << "Now i, j = " << i << ", " << j << ".\n" << endl;

	job sue = { "Susan Yaffee", 73000.60, 7 };
	job sidney = { "Sidney Taffee", 78060.72, 9 };
	cout << "Before job swapping:\n";
	Show(sue);
	Show(sidney);
	Swap(sue, sidney);		// uses void Swap(job&, job&)
	cout << "\nAfter job swapping:\n";
	Show(sue);
	Show(sidney);
	return 0;
}

template <typename T>
void Swap(T &a, T &b) {			// 通用版本
	T temp;
	temp = a;
	a = b;
	b = temp;
}
template <> void Swap<job>(job &j1, job &j2) {	// 显示具体化版本
	double t1;
	int t2;
	t1 = j1.salary;
	j1.salary = j2.salary;
	j2.salary = t1;
	t2 = j1.floor;
	j1.floor = j2.floor;
	j2.floor = t2;
}
void Show(job &j) {
	cout << j.name << ": $" << j.salary << " on floor " << j.floor << endl;
}

输出:
i, j = 10, 20.
Using compiler-generated int swapper:
Now i, j = 20, 10.

Before job swapping:
Susan Yaffee: $73000.60 on floor 7
Sidney Taffee: $78060.72 on floor 9

After job swapping:
Susan Yaffee: $78060.72 on floor 9
Sidney Taffee: $73000.60 on floor 7

笔记
 
 
 
 
 


Reference:

  • 《C++ Primer Plus》第六版 Stephen Prata 著
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值