• C++的优秀特性4:指针


    (转载请注明原创于潘多拉盒子)

    其实指针不是C++的特性,而是地地道道的C的特性。有人说C++继承了C的指针,实在是败笔,造成内存泄漏云云,纯粹是不懂。可以这么说,如果没有指针,C++会逊色很多,应用的场景也会大大缩小。

    指针是一个变量,这个变量和一个int型的变量没有太大的不同,只是这个变量里存储的是它指向的对象的内存地址。

    指针可以指向任何对象,包括内置类型(int、long、double、float等),对象类型,函数入口,甚至另外一个指针或者可以指向任何类型 。

    涉及指针的操作符包括:定义指针(*)、解引用(*)、取地址(&)、取成员(->)、偏移解引用([]),偏移(+、-)、求偏移(-)。

    先看看几种指针的例子:

    1. 指向int型变量的指针:int* p = new int(0);
    2. 指向对象的指针:Widget* p = new Widget();
    3. 指向函数的指针:int (*p)(int n) = factorial; 这里p是指向已经定义的函数factorial的函数指针。
    4. 指向指针的指针:Widget** pp = &p;
    5. 可以指向任何类型的指针:void* any = NULL; 这里的any是指向任何类型变量的指针。比如any = p; 或是any = pp; 甚至any = &pp; 都是合法的。

    对于#1和#2的情况,大家应该已经比较熟悉,这里就不赘述了。

    对于函数指针,在C语言实现动态方法绑定中非常有用。在C++中,更多的是通过接口虚函数覆盖(override)来代替。在某些兼容C程序动态行为绑定的例子中,可以采用函数指针。

    比如我们可以根据用户输入的命令,定义对应的处理函数:

    typedef bool (*command_process)(int argc, char** argv);
    
    bool start(int argc, char** argv)
    {
        // implementations
    }
    
    bool stop(int argc, char** argv)
    {
        // implementations
    }
    
    bool write(int argc, char** argv)
    {
        // implementations
    }
    
    
    bool read(int argc, char** argv)
    {
        // implementations
    }
    
    // assign processors to names
    std::map<std::string, command_process> processors;
    processors["start"] = start;
    processors["stop"] = stop;
    processors["write"] = write;
    processors["read"] = read;
    
    // use processors to process commands
    std::string command = "start";
    processors[command](argc, argv);  // 调用名称“start”对应的处理函数,实现动态效果
    

      比较有意思的是可以指向任何类型的变量的指针,比如:

    // 为了简单,这些变量全部定义在栈上,其实可以是new出来的
    int n = 256;
    double x = 3.14159265;
    Widget w;
    
    // 定义一个任意指针
    void* any = NULL;
    
    // 这个指针可以指向int类型的变量
    any = &n;
    
    // 也可以指向double型
    any = &x;
    
    // 或者是一个对象
    any = &w;
    
    // 但是,如果想对该指针解引用,则必须用reinterpret_cast
    Widget* pw = reinterpret_cast<Widget>(any);
    
    // 然后就可以调用了,安全性需要程序员自己保证,如果类型不对,程序可能crash。
    pw->widgetMethod();
    

    所以,除非非常必要,不要使用任意指针。  

    指针是可以偏移解引用的,即使这个指针不是指向一个数组头部:p[i]等价于*(p+i)。这里的i不必是非负整数,还可以是负整数。比如p[-4]是合法的。

    相同类型的指针之差是合法的,比如

    int* begin = new int[100]; 
    int* end = begin+100; 
    int size = end - begin;     // 这是合法的,size = 100,表示begin和end之间的变量的个数
    

      

  • 相关阅读:
    一、dynamic
    一、提问方式
    金额大写
    1、过滤敏感字符
    一、简单的移动端tab头部二级下拉导航栏,向下弹出,向上隐藏
    一、简单的图片上传并预览功能input[file]
    【2019-11-16】做人和做企业是一个同心圆
    【2019-11-15】销售门槛低,但前途无量
    【2019-11-14】乐观扩宽了自己想象的范围
    【2019-11-13】看到别人的是孤独,其实是独处
  • 原文地址:https://www.cnblogs.com/bqzhao/p/3541924.html
Copyright © 2020-2023  润新知