zoukankan      html  css  js  c++  java
  • C++类指针初始化

    上面的代码会打印“A”。
    C++ 类指针定义的时候没有初始化的时候,居然可以安全的调用类内部的成员函数而不出错。
    在网上查了一下:
     
    初始化为NULL的类指针可以安全的调用不涉及类成员变量的类成员函数而不出错,但是如果类成员函数中调用了类成员变量则会出错,既然赋值为NULL的情况都可以使用,那么自然不初始化的类指针同样满足这类情况。
     
    假设现在有一个简单的类定义如下:
    class Test
    {
    public:
        void func(){cout << "hahaha" << endl;}
        int get(){return a+b;}
        Test():a(1),b(2){}
    public:
        int a,b;
    };
    而之后编译器会自动将这个类转换成:
    class Test
    {
        int a,b;
    };
    void _test_func(Test * this);
    int _test_get(Test* this);
    ........


    类中的函数被编译器静态编译了,所有非虚函数(虚函数呢?别急,待会会解释到)都可以调用,因为函数地址编译期间已经确定。我们知道,类中的成员函数都是通过this指针调用成员变量的,编译器会将this指针作为默认参数传给类成员函数的,如myclass.function(int a,int b) --> function(&myclass,int a,int b)
    添加main函数如下:
    int main()
    {
    Test *p=NULL;
    p->func();//正确,没有调用成员变量,没有使用空的this指针
    p->get();//错误,this指针为空,通过this指针调用变量所以出错
    return 0;
    }
    运行结果如上,没有调用成员变量的func()函数正确执行,调用了成员变量的get()函数错误。两者其实都传入了空的this指针,前者没出错仅仅是因为没有调用this指针,而后者调用了。(此时p-func()和p->get()等同于func(NULL),get(NULL)......)是对象指针为NULL,而调用成员函数的时候,函数地址是编译期间确定的,成员函数不通过对象指针(也即当前的p指针)去调用,对象指针仅仅作为参数传入函数然后去调用成员变量。
          好现在问题来了,如果是虚函数呢,因为虚函数要通过this指针计算vptr,然后找到vtable,然后dispatch。因为this指针为空,所以在找vtable时候就会coredump了。总之这类情况下,一切调用了this指针的函数都会出错,而完全不调用this指针的成员函数则没问题。
    总结:任何时候定义指针的时候一定要初始化,这是良好的习惯,这个问题最初是由于当时写程序疏忽造成的,然而错有错着居然编译通过,所以当时一直没发现这个手误,现在追本溯源也算是对c++的内部机制有了更深的了解,不过也提示自己不能有侥幸心理,一定要养成良好的编程习惯,不管对于自己还是对于以后合作的伙伴都是一件好事。
  • 相关阅读:
    makefile ifeq ($(LANG),) 判断操作系统
    MIPS 指令集速查
    ps ef|grep mh* 命令
    ulimit c unlimited 命令
    kill 9 2402 命令
    chmod R 777 命令
    计算机网络总结
    source 命令
    ./ 命令
    reboot f 命令
  • 原文地址:https://www.cnblogs.com/ryanzheng/p/8452699.html
Copyright © 2011-2022 走看看