C++ 构造函数小错误备记
一个简单的获取数独题目的python脚本

C++基本概念之动态联编与静态联编

皮贝贝 posted @ 2010年8月19日 17:55 in 岁月舍利 with tags c++ , 3970 阅读

C++基本概念之动态联编与静态联编

        昨个儿,一同学打电话问我,这两个名词,事实上,我以前倒没大注意,在课堂的时候听说过一次,后来就再没印象了。缘故是我看的C++语法概念书就那一本:CTPL, 而且上面并未着重提出,这个概念估计是国内的专属吧,概念是概念,理论还是有的。同学的引出点是关于转型对于函数调用的影响。

        Java 的世界里不仅没有指针,更没有虚函数的概念,当然这个是针对使用者而言。且不说指针,虚函数的省略确实减轻了设计的负担,因为就C++的概念放到java里说,普通成员函数的重载都是虚函数重写,所以你只要对父类的某个方法重写了,以为着你达到了C++的虚函数效果了。所以说,Java还是蛮简单的,将一切复杂的东西抽取成简单的表面化。

1 C++ 对象模型

        这里为了简单,没有考虑继承等因素。

        了解对象模型对这个问题会有知其所以然的豁然,Stroustrup 设计的 C++ 对象模型在当前的编译器界仍然广为接受. 首先,我们知道,一个对象在内存中实在存在的(对比类)。从C的层次来讲,我们访问内存区域,需要指定如何访问,这就是类型存在的意义:指明了内存中的存储结构。如我们访问一块儿 char 类型数据,编译器一看是一 char 的形式访问,自然的就提取内存的前1个字节。C++ 的对象与这类 POD 的对象有着实在的差别,因着增加了成员函数,而且有动态识别的信息。对于各个类内各个类型的数据,是如何存储的呢?

1.1 普通成员变量

         单就这点来说,C的 struct 模型就足够了,而且为了C的兼容,所以普通成员函数仍然排列在对象内存区域。顺带一说,其他类型的成员都在这个内存结构之外。所以一个简单的无虚函数的对象来说,sizeof(object)其实就是C 中struct 的大小,也就是各个成员变量域大小的总和(要考虑对齐因素哦)。

1.2 普通成员函数,静态成员函数,静态成员变量

        这些被放在对象内存结构之外了。对于静态类的,可以想象成是全局。这些信息是不像虚函数,有动态调用的公用,所以简单的处理就可以了。所以在编译的时候,这些函数调用都实际上生成了一个真是的函数地址。

1.3 虚函数

        虚函数引来的问题就多了,因为他不仅引入了动态联编,而且引起了动态识别。Stroustrup 的方案是设置了一个虚表,在虚表里存储着这些特殊的信息:虚函数位置,动态类型信息。而这个虚表是不在对象内存结构中,为了能找到这个虚表,在对象的内存结构中有一个固定位置的插槽,这里存放的就是虚表的位置(地址)。 你可以通过这样的例子来证实这个插槽:

 

class TestClass {
    int value;
    void fun();
};

        然后另一个对象:

class TestClass {
    int value;
    virtual void fun();
};

        检验两个类的 sizeof, 然后再在第二个类里多加几个虚函数试试,sizeof结果依然不变。vs2005的结构是 4 和 8, 这个插槽(指针)的大小是4个字节,而且通过内存调试知道这个插槽恰恰在第一个DWORD区域里。

        在编译的时候,因为对象的类型信息编译器不知道,也不需要知道,所以这种二次寻址的方式恰恰实现了虚函数的动态调用功效。

2 转型

        普通的转型其实是告诉编译器的,是告诉编译器以某种方式来访问。如果是访问普通成员变量,就以你指定的类型来访问这个内存区域的某个域。如果访问的是普通成员函数,编译器知道你的转型类型,所以到某个类型的普通成员函数中找到这个函数,然后生成这个函数的真实地址,填充到你的程序二进制码中。静态成员函数和变量类似。

        但是对于虚函数来说,编译器知道这是虚函数,所以会通过插槽找,首先,这个插槽的位置是固定的,所以你无论怎么转型(继承链上),它(编译器)得到的插槽的值是固定的,所以你访问的虚表是你对象的真实类型的虚表,所以你调用的虚函数永远都是正确的。

        总之,这样的原则记住就好:对于普通成员函数,转型只是转换对象内存访问方式;对于虚函数,转型并不会引起虚函数的调用转变,还是真实的;对于其他的类型数据,转型便调用指定类型的函数, 意味着调用的不是真实的自己的,即使调用的在自己内部并不存在。

 


 

Date: 2010-08-19 09:50:45

HTML generated by org-mode 6.33x in emacs 23

 

Avatar_small
전설 서구 说:
2021年2月28日 15:20

Thanks for your insight for your fantastic posting. I'm exhilarated I have taken the time to see this. It is not enough; I will visit your site every day. visit here

Avatar_small
Karnataka 1st PUC Pr 说:
2022年8月25日 12:57

Karnataka 1st PUC Important Model Question Paper 2023 is Download on the Official Page and Here. Karnataka Board has Announced the PUC Important Model Question Paper 2023 in Online Mode. Candidates who are Appearing the Karnataka PUC Annual Examination, Those can Check and Download the Important Model Question Paper 2023. Karnataka 1st PUC Previous Paper 2023 Karnataka 1st PUC Exam Important Model Question Paper 2023 Details are Given Below. PUC Second Year Arts, Science, and Commerce Group Board Examination Commences From February 2023 and Terminates on 20th February 2023. The 1st PUC Practical Exam Conduct From January 2023.

Avatar_small
jnanabhumiap.in 说:
2024年1月26日 02:17

JNANABHUMI AP provides a CBSE syllabus for all classes for the academic year 2024 has been designed as per the guidelines of the CBSE Board. The syllabus offers a conceptual background and lays the groundwork for the Class 10 Board exams. jnanabhumiap.in By visiting the page, students will find the downloadable pdf of the reduced CBSE 10th Syllabus along with the deleted portion of the syllabus for each subject. So, students are advised to prepare for the exam, as per the syllabus mentioned here.


登录 *


loading captcha image...
(输入验证码)
or Ctrl+Enter