Nonstatic Member Functions
One C++ design criterion is that a nonstatic member function at a minimum must be as efficient as its analogous nonmumber function. This is achieved by internally transforming the member instance into the equivalent nonmember instance.
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. Rewrite each direct access of a nonstatic data member of the class to access the member through the this pointer.
3. Rewrite the member function into an external function, mangling its name so that it's lexically unique.
Name Mangling
In general, member names are made unique by concatenating the name of the member with that of the class. Function names are made unique by internally encoding the signature types (argument lists are referred to as the function signature) and concatenating those to the name.
class Point
{
public:
void x__5Point(float newX);
float x__5Point();
}
class Point
{
public:
void x__5PointFf(float newX);
float x__5PointFv();
}
By encoding the argument list with the function name, the compiler achieves a limited form of type checking across separately compiled modules. For example, if a print function is defined as
void print (const Point3d &) {...}
but was accidentally declared and invoked as
void print (const Point3d);
the unique name mangling of the two instances would cause any invocation of the incorrect instance to fail to be resolved at link time - sometimes optimistically referred to as type-safe linkage. I say "optimistically" because the process catches function signature errors only; a misdeclared return type still goes unnoticed.
Virtual Member Functions
If normalize() were a virtual member function, the call
ptr->normalize();
would be internally transformed into
(*ptr->vptr[1])(ptr);
the second ptr represents the this pointer.
The explicit invocation of a virtual function using the class scope operator is resolved in the same way as a nonstatic member function.
//explicit invocation suppresses virtual mechanism
register float mag = Point3d::magnitude();
is transformed internally into:
register float mag = magnitude__7Point3dFv(this);
Objects do not support polymorphism. The invocation of a virtual function through a class object should always be resolved by your compiler as an ordinary nonstatic member function.
Static Member Functions
The primary characteristic of a static member function is that it is without a this pointer. The following secondary characteristics all derive from that primary one:
1. It can NOT directly access the nonstatic members of its class
2. It can NOT declared const, volatile, or virtual
3. It does NOT need to be invoked through an object of its class, although for convenience, it may.
Taking the address of a static member function always yields the value of its location in memory, that is, its address. The type of its address value is not a pointer to class member function but the type of a nonmember pointer to function.
No comments:
Post a Comment