C++C++2.0

C++ Function语意

2017-05-21  本文已影响19人  ffusheng

C++ 支持3种类型member function:static,nonstatic,virtual下面逐一介绍。

Nonstatic Member Functions(非静态成员函数)

C++的设计准则之一: 就是nonstatic member function至少必须和一般的nonmember function有相同的效率。意思是:

void test(const Foo&);    // nonmember function
void Foo::test() const;      // nonstatic member function

选择下一种方式不会增加任何额外开销,这是因为编译器内部已将"member 函数实例"转换为对等的"nonmember函数实例"。
比如

// 代码没什么实际意义,只作演示
void test(const Foo &it)       // 非成员函数
{
      return sqrt(this->x * this->x + this->y * this->y + this->z * this->z);
}
void Foo::test() const          // 成员函数
{  
       return sqrt(x * x + y * y + z * z);
}

而Foo::test() const会被改造:

void Foo::test(const Foo *const this)
{  
       return sqrt(this->x * this->x + this->y * this->y + this->z * this->z);
}

然后再被改造为一个外部函数和name mangling过程。

extern Foo_3testF(const Foo *const this);

则原来的每一个调用操作都会被变为:

obj.test() 变为: test(&obj);
ptr->test() 变为 : test(ptr);
static Member Functions(静态成员函数)

Static member function主要特性是它不属于某一个对象,也就是说它没有this指针。也因此,它会有下面特性:

如果取用一个static member function的地址,获得的将是其在内存中的位置,也是其地址,由于static member function没有this指针,所有地址类型并不是一个"指向class member function的指针",而是一个"nonmember函数指针",也就是说:

int Foo::static_test() // static member function
&Foo::static_test();
会得到:
int (*)();
而不是:
int (Foo::*)();
Virtual Member Functions(虚拟成员函数)

为了支持virtual function机制, 必须要能够对于多态对象有某种形式的"执行期类型判断法" 比如这种调用:ptr->z(),需要ptr在执行期的相关信息。
最直截了当的方法就是:把必要的信息加在ptr上

如果这些信息不能够和指针放在一起,那么下一个考虑的就是放在对象本身。但是哪些对象需要这些信息?

struct(class) Foo{
    int num;
    string str;
};

显然这样的对象是不需要这些信息的。那么很容易想到包含了有virtual函数的需要多态信息。
在实现上,我们可以在每一个多态的class object身上增加2个members:

然而这些由编译器准备好。执行期要做的,只是在特定的virtual table slot中激活virtual fucntion。
比如:

ptr->z();

那编译器如何设定virtual fucntion的调用呢?

那么这些信息可以使得编译器将该调用转化为(*ptr->vtpr[4])(ptr);唯一在执行期知道的信息是: slot4所指的到底是哪一个z函数实例。

以上这些推论会经过下面各种代码实践。

上一篇 下一篇

猜你喜欢

热点阅读