C++ 类的本质 札记

原文地址:http://hi.baidu.com/chzhao007/blog/item/e9dbc5ac1191bc034b36d6df.html

前几天,我竟被只小鸟小觑了一下,我承认本人blog中张贴出来的代码确实一般,所以我得在此在重审一下:本人张贴出来的代码都不是本人最终代码!
本人blog中到现在确实用C写的代码很多,但不代表本人不崇尚C++的对象编程,只不过本人现在从事的许多方面用C和汇编搞起来比较方便,所以用C写东东比起C++来随手。为了使本人blog阐述的东东近于完善,在此就写下本人对C++类的一点点本质认识。在此再次重审:本人blog不代表本人现在真实水准。谁都要有点看家本事,否则在这社会上还真不好混,做为看家本事,一般是不外泄的哦。

本人在此不讨论理论上什么叫C++类(什么类代表汽车,鸭子的不会在此文中找到),在此只在机码层看看类到底是如何实现和运行的。

在这里我先定义一个测试用的类

class one{

public:

    one():a(10){}
    ~one(){}
    void seta(int a) { this->a = a;}
    int geta(void) { return a; }
    void setb(int b) { this->b = b;}
    int getb(void) { return b;}

private:

    int a,b;

};

接下来让我们定义一个类元素

one testone;

下面让我们看看定义的这个testone在内存中占多大

std::cout<<sizeof(testone)<<"\n";        //运行之后你会发现 testone在内存中只有8个字节 就是两个int的大小

在此我们完全可以认为 one 等同于

          struct{ 
                     int a; 
                     int b; 
                         }one;

如果你很想耍帅的话 你可以这样动态声明一个类     test* one = (one *)new int(2);

现在让我们再定义一个one元素 one testtwo; 同样testtwo的大小也是8字节。现在我们就有一个疑问喽,testone与testtwo大小相同但不是同一个实体,它们是如何和 one() ~one() seta() geta()等函数联系到一起的?

现在让我们在汇编级看看

       testone.seta(1);
00401098 6A 01                push        1
0040109A 8D 4D EC             lea         ecx,[ebp-14h]
0040109D E8 72 FF FF FF       call        @ILT+15(one::seta) (00401014)
       testtwo.seta(2);
004010A2 6A 02                push        2
004010A4 8D 4D E4             lea         ecx,[ebp-1Ch]
004010A7 E8 68 FF FF FF       call        @ILT+15(one::seta) (00401014)

我们发现 testone和testtwo调用它们各自的seta时用到同一个地址 00401014,在此可以肯定,同一个类one定义的元素共用类one定义的方法函数。

那么我们又可以推测出testone和testtwo的不同点是只有各自的int a\ int b 变量的地址不同了。在汇编码中我们又发现ebp - 14h和ebp - 1ch正好相差8字节。我的代码

one testone;
one testtwo;

定义的testone和testtwo是相挨着的,所以分内存时testtwo会紧跟testone之后。

在此我们可以总结一下了c++类的实现,编译器将

结构     struct{ 
                     int a; 
                     int b; 
                         }one;

一系列的函数方法

    one():a(10){}
    ~one(){}
    void seta(int a) { this->a = a;}
    int geta(void) { return a; }
    void setb(int b) { this->b = b;}
    int getb(void) { return b;}

自动进行了捆绑。这就好比生产线,生产设备是固定的,只是进出的零件在换罢了,而这些零件是事先处理(声明)后与此生产线相配的一套零件。

通过以上本人对c++类本质的简述,想毕各位可以很轻松的用c语言实现c++的类了吧(只要在加入结构与方法的固化就O了)。

在此本人在多述几句,功夫高手草朩皆兵,万物皆刃。编程注重的是思想不要固化在你所学的语言之上,要学会万化自然。

原文地址:https://www.cnblogs.com/wangkangluo1/p/2153645.html