Programming language evolves always along with Compiler's evolvement

The Semantics of Function

  • C++ supports three flavors of member functions: static, nonstatic, and virtual. Each is invoked differently; those differences are the topic of the next section. (A short quiz: Although we cannot say with certainty whether normalize() and magnitude() are virtual or nonvirtual members, we can safely discount the functions as being static, since both (a) directly access the nonstatic coordinate data and (b) are declared to be const members. Static member functions may not do either.)

Varieties of Member Invocation

  • A common opinion was that virtual functions were simply a kind of crippled pointer to function and thus redundant…, Therefore, the argument went, virtual functions were simply a form of inefficiency

Non-static Member Functions

  • One C++ design criterion is that a non-static member function at a minimum must be as efficient as its analogous nonmember function.
  • This is achieved by internally transforming the member instance into the equivalent nonmember instance.
  • In practice, however, the member function is transformed internally to be equivalent to the nonmember instance. Following are the steps in the transformation of a member function:
    • 1. Rewrite the signature to insert an additional argument to the member function that provides access to the invoking class object. This is called the implicit this pointer;
    • 2. if the member function is non-const, insert Class * const this;
    • 3. if the member function is const, insert const Class * const this;
    • 4. Rewrite each direct access of a non-static data member of the class to access the member through the this pointer;
    • 5. Rewrite the member function into an external function, mangling its name so that it's lexically unique within the program.
  • The invocation of member function will be internally transformed, with help of copy constructor and the named returned value (NRV) optimization.

Virtual Member Functions

  • (* ptr->vptr[ 1] ) ( ptr);
  • vptr represents the internally generated virtual table pointer inserted within each object whose class declares or inherits one or more virtual functions. (In practice, its name is mangled. There may be multiple vptrs within a complex class derivation.)
  • 1 is the index into the virtual table slot associated with normalize().
  • ptr in its second occurrence represents the this pointer.
  • Objects do not support polymorphism, but the pointer and reference support.
  • This is significantly more efficient if magnitude() is declared inline. The explicit invocation of a virtual function using the class scope operator is resolved in the same way as a nonstatic member function:

Static Member Functions

  • It can not directly access the non-static members of its class.
  • It can not be declared const, volatile, or virtual.
  • It does’t need to be invoked through an object of its class, although for convenience, it may.
  • A static member function, of course, is also lifted out of the class declaration and given a suitably mangled name.
  • Taking the address of a static member function always yields the value of its location in memory, that is, its address. Because the static member function is without a this pointer, the type of its address value is not a pointer to class member function but the type of a nonmember pointer to function.
  • That is,&Point3d::object_count();yields a value of type。unsigned int (*)();not of type unsigned int ( Point3d::* )();
  • Static member functions, by being this-less and therefore of the same type as an equivalent nonmember function, also provide an unexpected solution to the problem of mixing C++ with the C-based X Window system with regard to the use of callback functions. Take a look at DECLARE_DYNCREATE(class_name) of MFC.

Virtual Member Functions

  • We've already seen the general virtual function implementation model: the class-specific virtual table that contains the addresses of the set of active virtual functions for the class and the vptr that addresses that table inserted within each class object. In this section, I walk through a set of possible designs evolving to that model and then step through that model in detail under single, multiple, and virtual inheritance.
  • There needs to be some information associated with ptr available at runtime such that the appropriate instance of z() can be identified, found, and invoked. Perhaps the most straightforward but costly solution is to add the required information to ptr. Under this strategy, a pointer ( and, implicitly, a reference as well) holds two pieces of information:
    • 1, The address of the object it refers to;
    • 2. Some encoding of the object’s type or the address of a structure containing that information.
  • The problem with this solution is two-fold. First, it adds significant space overhead to the use of pointers regardless of whether the program makes use of polymorphism. Second, it breaks link compatibility with C.
  • That is why the keywords virtual is introduced to C++, which indicates that the object shall be added the information in support of polymorphism.
  • In C++, polymorphism “exhibits” itself as the potential addressing of a derived class object through a pointer or reference of a public base class.
  • How might the table containing the virtual function addresses be constructed? In C++, the set of virtual functions capable of being invoked through an object of its class is known at compile time. Moreover, this set is invariant. It cannot be added to nor can a virtual instance be replaced at runtime. The table, therefore, serves only as a passive repository. Since neither its size nor its contents change during program execution, its construction and access can be completely handled by the compiler. No runtime intervention is necessary.
  • Having the address available at runtime, however, is only half the solution. The other half is finding the address. This is accomplished in two steps:
    • 1. To find the table, an internally generated virtual table pointer is inserted within each class object.
    • 2. To find the function’s address, each virtual function is assigned a fixed within the table.
  • This is all set up by the compiler. All that is left to do at runtime is invoke the function addressed within the particular virtual table slot.
  • The virtual table is generated on a per-class basis. Each table holds the addresses of all the virtual function instances “active” for objects of the table’s associated class.
  • Each virtual function is assigned a fixed index in the virtual table. This index remains associated with the particular virtual function throughout the inheritance hierarchy.
  • There are three possibilities:
    • 1, It can inherit the instance of the virtual function declared within the base class. Literally, the address of that instance is copied into the associated slot in the derived class’s virtual table;
    • 2. It can override the instance with one of its own. In this case, the address of its instance is placed within the associated slot;
    • 3. It can introduce a new virtual function not present in the base class. In this case, the virtual table is grown by a slot and the address of the function is placed within that slot.
  • Within a single inheritance hierarchy, the virtual function mechanism is well behaved; it is both efficient and easily modeled. Support for virtual functions under multiple and virtual inheritance is somewhat less well behaved.

Virtual Functions Under MI

  • The complexity of virtual function support under multiple inheritance re-volves around the second and subsequent base classes and the need to adjust the this pointer at runtime.
  • The general rule is that the this pointer adjustment of a derived class virtual function invocation through a pointer (or reference) of a second or subsequent base class must be accomplished at runtime. That is, the size of the necessary offset and the code to add it to the this pointer must be tucked away somewhere by the compiler.

From:<<Inside C++ Object Model>>

C++ Knowledge series 4的更多相关文章

  1. Java Knowledge series 4

    JVM & Bytecode Has-a or Is-a relationship(inheritance or composition) 如果想利用新类内部一个现有类的特性,而不想使用它的接 ...

  2. C++ Knowledge series 1

    Programming language evolves always along with Compiler's evolvement. 1. The C++ Object Model: Strou ...

  3. C++ Knowledge series Template & Class

    Function Function is composed of name, parameter (operand, type of operand), return value, body with ...

  4. C++ Knowledge series Inheritance & RTTI & Exception Handling

    Inheritance The pointer or reference to base class can address/be assigned with any of the classes d ...

  5. C++ Knowledge series Conversion & Constructor & Destructor

    Everything has its lifecycle, from being created to disappearing. Pass by reference instead of pass ...

  6. C++ Knowledge series STL & Const

    Thank to the pepole who devote theirself to the common libs. STL(http://www.cplusplus.com/reference/ ...

  7. Java Knowledge series 7

    Pepole who make a greate contribution on common libaraies deserve our respect. Component(Widget) / S ...

  8. C++ Knowledge series 2

    Programming language evolves always along with Compiler's evolvement The semantics of constructors O ...

  9. Java Knowledge series 5

    Interface from user, not from implementor.(DIP) Interface-Oriented Programming. Interface or Abstrac ...

  10. Java Knowledge series 3

    JVM & Bytecode Abstract & Object Object in Java (1) 所有东西都是对象object.可将对象想象成一种新型变量:它保存着数据,但可要求 ...

随机推荐

  1. P3703 [SDOI2017]树点涂色 LCT维护颜色+线段树维护dfs序+倍增LCA

    \(\color{#0066ff}{ 题目描述 }\) Bob有一棵\(n\)个点的有根树,其中1号点是根节点.Bob在每个点上涂了颜色,并且每个点上的颜色不同. 定义一条路径的权值是:这条路径上的点 ...

  2. U19464 山村游历(Wander) LCT维护子树大小

    \(\color{#0066ff}{ 题目描述 }\) 在一个偏远的小镇上,有一些落后的山村.山村之间通过一些道路来连接.当然有的山村可能不连通. 一年当中会发生很多大事,比如说有人提议要在山村\(i ...

  3. P3379 【模板】最近公共祖先(LCA)(LCT)

    \(\color{#0066ff}{ 题目描述 }\) 如题,给定一棵有根多叉树,请求出指定两个点直接最近的公共祖先. \(\color{#0066ff}{输入格式}\) 第一行包含三个正整数N.M. ...

  4. 树链剖分【洛谷P1505】 [国家集训队]旅游

    P1505 [国家集训队]旅游 题目描述 Ray 乐忠于旅游,这次他来到了T 城.T 城是一个水上城市,一共有 N 个景点,有些景点之间会用一座桥连接.为了方便游客到达每个景点但又为了节约成本,T 城 ...

  5. SIGHUP信号

    SIGHUP会在以下3种情况下被发送给相应的进程:1.终端关闭时,该信号被发送到session首进程以及作为job提交的进程(即用 & 符号提交的进程)2.session首进程退出时,该信号被 ...

  6. Xcode上传appstore 出现 Found an unexpected Mach-O header code: 0x72613c21 错误

    网上说是静态库的问题

  7. Django 06 Django模型基础1(ORM简介、数据库连接配置、模型的创建与映射、数据的增删改查)

    Django 06 Django模型基础1(ORM简介.数据库连接配置.模型的创建与映射.数据的增删改查) 一.ORM系统 #django模型映射关系 #模型类-----数据表 #类属性-----表字 ...

  8. CodeForces - 476B -Dreamoon and WiFi(DFS+概率思维)

    Dreamoon is standing at the position 0 on a number line. Drazil is sending a list of commands throug ...

  9. 8.9zju集训日记

    和新队员的第一次比赛,前期开题方向基本正确,签到的速度比较快,中期读了旋转卡壳,矩阵和km的三道题目,都有一定的想法,但三个人意见不同没有往一个方向想,但其实旋转卡壳和km的题目思路几乎都对了,但是旋 ...

  10. 安装openstack时遇到的错误

    学习opensatck的第一步是安装DevStack来进行本机操作 1. 下面命令没有权限,解决办法:切换到root用户下执行sudo -s echo "stack ALL=(ALL) NO ...