Effective C++ 24,25

24.在函数重载和设定参数缺省值间要慎重选择。

获得一种类型的数据的最小值或最大值,对于c中,一般使用在<linits.h>中定义的各种宏如INT_MIN 来进行表示,但是这样无法进行泛型编程,即对应如何一种类型T返回对应类型的最小或最大值。而在c++中一般如此获得

std::numeric_limits<T>::min()

c++在<limits>中定义了类模版numeric_limits,用来返回对应类型的最小最大值,这是一个很有用的东西。

然后继续讨论函数重载与参数缺省值,如以下情况:

int fun(){
	return 1;
}
int fun(int a){
	return a;
}
int fun(int a=1,int b = 0){
	return a+b;
}

对于第3个函数,当没有参数和只有一个参数时会与前两个函数冲突,但是对于第三个函数,即有默认值的情况下,其能直接具有全部三个函数的功能,使用默认值的函数其效果更好且功能更多。

但是有时找不到一个好的缺省值。当对5个以内的值求和时,可以设每个参数的默认值为0,但是当对5个以内的值进行求平均数时,要获得传入参数的个数,无法通过函数的参数来实现,所以只能重载5个函数,即只有一个,两个,3,4,5个函数的所有情况。

另一种必须使用重载函数的情况是:想完成一项特殊的任务,但算法取决于给定的输入值。就是说函数由于输入参数不同进行操作不同的这类函数要重载,如类的构造函数。

25.避免对指针和数字类型的重载。

如函数 void f(int x);和void f(int * p);这两个函数的,重载是会出错,简单来说对于实参为0,即0是什么?0即是指针有是int,但事实上在编译器中运行

void f(int* x){
	cout<<"int_ptr"<<endl;
}
void f(int x){
	cout<<"int"<<endl;
}
int main(){
	f(NULL);

结果为 输出 int ,即0是一个int。人们认为一个调用具有多义性时,编译器却不这么干。

NULL的类型是就是int,要使其调用 f(int*)这个函数,就必须如此做

	f(static_cast<int*>(NULL));

但是如果将NULL定义为UL,即无符号整数

#define NULL 0UL

在调用f(NULL)又会报错,重载不明确,NULL即可以是int也可以是int*

但是如果又将f(int)函数改为

void f(unsigned long x);

又会正确,因为NULL是unsigned long,而f函数中参数也是。

而如果我们需要一个任何地方都可以使用的任意类型的NULL指针,就必须设计一个产生NULL指针对象的类:

#ifdef NULL
#undef NULL
#endif
class NullClass{
public:
	template<class T> //模版
	operator T*()const{return 0;}//返回一个T*的null指针。
};
const NullClass NULL;//NULL的常量

然后再次使用 f(NULL)的时候,就会调用隐式的类型转换,获得一个对象T类型的null指针。但是这样还不够,改进:

首先我们只需要一个NullClass对象,所以给这个类一个名字是没有必要的,定义一个匿名类并使NULL成为这种类型。

其次,我们想让NULL可以转换为如何类型的指针,那就要能够处理成员指针(指 指向类中函数的指针),要再定义一个成员模版,将类C与所有类型T转换为类型 T C::*。

最后要防止用户取NULL的地址,NULL要表现的像指针一样,但其值不是指向真正的0,所以要对用户隐藏。

改进后如下:

class {
public:
	template<class T> //模版
	operator T*()const{return 0;}//返回一个T*的null指针。
	template<class C,class T>
	operator T C::*() const{return 0;}//转换任意类型的null成员指针
private:
	void operator&() const ;//隐藏NULL的地址
}NULL; //只有一个名字为NULL的对象
时间: 2024-08-26 01:04:44

Effective C++ 24,25的相关文章

Java集合-5. (List)已知有一个Worker 类如下: 完成下面的要求 1) 创建一个List,在List 中增加三个工人,基本信息如下: 姓名 年龄 工资 zhang3 18 3000 li4 25 3500 wang5 22 3200 2) 在li4 之前插入一个工人,信息为:姓名:zhao6,年龄:24,工资3300 3) 删除wang5 的信息 4) 利用for 循

第六题 5. (List)已知有一个Worker 类如下: public class Worker { private int age; private String name; private double salary; public Worker (){} public Worker (String name, int age, double salary) { this.name = name; this.age = age; this.salary = salary; } public

神经网络,25个术语

从神经网络说起:深度学习初学者不可不知的25个术语和概念(上) http://www.36dsj.com/archives/85406 1,神经元:2,权重:3,偏置:用来改变输入的范围.4,激活函数f(x):将输入信号翻译成输出信号.最常用的激活函数有Sigmoid.ReLU 和softmax.5,神经网络:训练神经网络,更新偏置值,目标是找到未知函数的一个近似值.6,输入层.输出层.隐含层,7,多层神经网络MLP,每一层上的神经元都和下一层上的神经元连接在一起,全互连网络(fully con

2.23/2.24/2.25 find命令 2.26 文件名后缀

2.23/2.24/2.25 find命令 2.26 文件名后缀 2.23/2.24/2.25 find命令 2.23 find命令   上 常用的几个 搜索文件which  whereis 安装 locate 模糊的搜索 不精准的搜索 ctrl a 光标移到命令最前面 ctrl e 光标移到命令最后面 ctrl u 删除光标前面的字符 find 搜索 find 路径  具体的条件 find 搜索文件类型  -type -d目录.-f文件.(-).-l链接 .-s socket文件.-c字符串

20.23 20.24 20.25 告警系统邮件引擎20.26 运行告警系统

20.23 20.24 20.25 告警系统邮件引擎把之前zabbix设置好的邮件拷贝到mail目录下cd /usr/local/sbin/mon/mailvim mail.sh 这个脚本的目的是做告警收敛的,就是服务没有恢复超过一定时间才会告警log=$1t_s=date +%s 当前的时间戳t_s2=date -d "2 hours ago" +%s 2个小时以 前的时间戳if [ ! -f /tmp/$log ] 如果 没有这个文件thenecho $t_s2 > /tmp

【总结】Effective java经验之谈,类与接口

转载请注明出处:http://blog.csdn.NET/supera_li/article/details/44940563 Effective Java系列 1.Effective java经验之谈,创建和销毁对象 2.Effective java经验之谈,泛型 3.Effective java经验之谈,类与接口 4.Effective java经验之谈,通用方法 5.Effective java经验之谈,枚举,注解,方法,通用设计,异常 6.Effective java经验之谈,并发编程

cacti多核cpu模板(2,4,8,12,16,24,32)

cacti的多核cpu监控模板,2,4,8,12,16,24,32 注意:0.87g版本不能直接导入,需要修改hash值为0021,0.88及以上可以直接使用 地址:http://down.51cto.com/data/2290168

关于BASE 24 ,BASE 64原理以及实现程序

关于BASE 24 ,BASE 64原理以及实现程序 来源 https://wangye.org/blog/archives/5/ 可能很多人听说过Base64编码,很少有人听说过Base24编码,Base24编码主要应用在序列号生成上,其实基本的算法思想都是一样的,只是编码的模式有点变化.Base64所对应的编码表是ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=共计64位.而Base24所对应的编码表是BCDF

JavaScript高级程序设计(第三版)学习笔记22、24、25章

第22章,高级技巧 高级函数 安全的类型检测 typeof会出现无法预知的行为 instanceof在多个全局作用域中并不能正确工作 调用Object原生的toString方法,会返回[Object NativeConstructorName]格式字符串.每个类内部都有一个[[Class]]属性,这个属性中就指定了上述字符串中的构造函数名. 原生数组的构造函数名与全局作用域无关,因此使用toString方法能保证返回一致的值,为此可以创建如下函数: function isArray(value)

Effective C++ 35,36,37

35.使公有继承体现 "是一个" 的含义. 共同拥有继承意味着 "是一个".如  class B:public A. 说明类型B的每个对象都是一个类型A的对象,A比B具有更广泛的概念.而B表示一个更特定的概念. 在C++中不论什么一个參数为基类的函数都能够实际取一个派生类的对象,仅仅有共同拥有继承会如此.对于共同拥有继承,如AB.若有两个函数 一个函数为 void fun1(A &a);还有一个函数为void fun2(B& b);则对于AB的两个对