zoukankan      html  css  js  c++  java
  • 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的对象
    









  • 相关阅读:
    Linux C Socket编程原理及简单实例
    clock_gettime 用法
    Linux未来监控tracing框架——eBPF
    eBPF监控工具bcc系列五工具funccount
    【转】如何测量电源纹波?
    【转】在网页中运行VB6程序
    如何为互阻抗放大器电路选择具有足够带宽的运算放大器
    互阻放大器的稳定工作及其评估
    【原创】OPA857 TEST模式使用
    [转]What you need to know about transimpedance amplifiers – part 1
  • 原文地址:https://www.cnblogs.com/bhlsheji/p/5173879.html
Copyright © 2011-2022 走看看