为什么可以不创建对象就调用类的成员函数?

http://bbs.51cto.com/thread-848191-1.html








以下代码是可以正常运行的
class Base 

public: 
    void print() 
    { 
        printf("print :Base!\n"); 
    } 
}; 
int main()
{
    Base* b=NULL; 
    b->print(); 
   return 0;
}
没有创建类对象,却可以调用类的不包含成员变量的成员函数。学校论坛上有人的解释是“编译器实际上是把所有的类成员函数改名(name mangling)并加上一个本类的this指针,使其非成员化。所以,在程序开始运行时,所有成员函数代码的地址已经确定,所有类对象共享, 而不像成员变量(非static)必须在实例化后才分配内存并且每个实例都拥有一份。”
但是我疑惑的是,为什么C++作为面向对象语言可以不创建对象就访问一个属于类的方法?这样做有什么好处?一个类方法虽然没有使用到类属性,但也应该是类行为,应该是这类对象才能够具备的,为什么可以随便调用?
至少在Java里面
Base b=null; 
    b->print(); //error,need Base b=new Base(); 
这样是错误的,必须创建对象。

最佳答案



 

1. 楼主求知精神值得学习
2. 给你解释的人说的基本上是正确的。
成员函数编译以后就是普通的函数,
比如Base的Print被改名为void Print_Base_xxxxx(Base* pBase);
那b->Print被转为Print_Base_xxxxx(NULL);

其实更激烈点的方式,比如Derived继承于Base,它实现了Print这个函数。
你在main里面调用
Derived* pDerived = NULL;
pDerived->Print;

再做一个假设,你想crack这个编译后的可执行程序。

你找个反汇编工具,看到函数调用call ptr[derived_print_xxx]类似这样一条语句,把它改为call ptr[base_print_xxx].再运行程序,你会发现调用的是Base的Print。

所以说成员函数和普通的非成员函数没有本质的区别(起码编译以后是这样),调用的方法也是一样的。
3. 编译器实现问题楼主不必深究。如果有兴趣你可以去windws mobile资源区看看ansi c++ standard,看看里面有没有对这个的实现做出具体的规定。如果c++ standard没有具体规定,那么不同的c++厂商怎么实现自己定。





 

多谢楼上。。。不过暂时还没有精力这么深入的研究,不过我会看的





 

嗯,多谢V哥,代码的实现问题基本理解,“所以说成员函数和普通的非成员函数没有本质的区别(起码编译以后是这样),调用的方法也是一样的。”
我只是想问,为什么C++要设计成这样,我觉得从面向对象概念上来讲,成员函数就应该和普通函数区分开来,一个类方法虽然没有使用到类属性,但也应该是类行为,应该是这类对象才能够具备的,为什么可以随便调用?
C++这么做有什么好处?
也许我钻牛角尖了,C++就是这么设计的,我也没啥办法。。。





 

成员函数与成员变量不同。成员函数,不需要反复的去声明、定义,可以节省好多空间。成员变量不能这么做,那是因为每个对象有所不同,当然,静态成员例外。




 
发布了11 篇原创文章 · 获赞 0 · 访问量 1万+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章