C++ – Virtual Function

留下评论

请说出你的思想, 简单而直接. –Brian Kernighan
As you will see, the primary layout and access-time overheads within C++ associated with the
virtuals, that is,
 the virtual function mechanism in its support of an efficient run-time binding, and
 a virtual base class in its support of a single, shared instance of a base class occuring multile
 times within an inheritance hierarchy.
Virtual functions support:
1. A table of pointers to virtual functions is generated for each class;
2. A single pointer to the associated virtual table is inserted within each class object(traditionally,
    this has been called the vptr). The type_info associated with each class in support of runtime type identification
    (RTTI) is also addressed within the virtual table, usually within the table’s first slot.
 
The compiler generates default constructor for the class when one of the following conditions is met:
1. member class object with default constructor
2. base class with default constructor
3. class with a virtual function
4. class with a virtual base class
The two misunderstandings about the default constructor:
1. That a default constructor is synthesized for every class that does not define one;
2. That the compiler-synthesized default constructor provides explicit default initializers for each data member
     declared within the class;
 
When are bitwise copy senmantics not exhibited by a class? There are four instances:
1. When the class contains a member object of a class for which a copy constructor exists;
2. When the class is derived from a base class for which a copy constructor exists;
3. When the class declares one or more virtual functions;
4. When the class is derived from an inheritance chain in which one or more base classes are virtual.
Question
Parent * ptrParent;
Parent cParent = *ptrParent;
We must use the member initialization list in the following cases in order for our program to compile:
1. when initializing a reference member;
2. when initializing a const member;
3. when invoking a base or member class constructor with a set of arguments.
the initialization order in the initialization list is according to the declaration list.
class X
{
     int i;
     int j;
 public:
     X(int val)
         : j(val), i(j) {}
};
 
Single inheritance without the support of virtual functions
Single inheritance with virtual functions,
Multiple inheritance,
Virtual inheritance
 
Polymorphism:
1. Introduction of a virtual table associated with class to hold the address of each declared virtual function. The size of this table
    in general is the number of virtual functions declared plus an additional one or two slots to support runtime
    type identification;
2. Introduction of the vptr within each class object. The vptr provides the runtime link for an object to efficently
    find its associated virtual table;
3. Augmentation of the constructor to initialize the object’s vptr to the virtual table of the class.  Depending on the
    aggressiveness of the compiler’s optimization, this may mean resetting the vptr within the derived and each base
    class constructor.
4. Augmentation of the destructor to reset the vptr to the associated virtual table of the class. It is likely to have been set to
    address the virtual table of the derived class within the destructor of the derived class. Remember, the order of
    destructor calls is in reverse: derived class and the base class. An aggressive optimizing compiler can
    suppress a great many of these assignments.
virtual inherentance????
Advertisements

C++ – 代码剖析

留下评论

class C10
{
protected:
int val1;
char val2;
};
class C11 : public C10
{
protected:
 char val3;
};
class C12 : public C11
{
protected:
 char val4;
};
int main(int argc, char* argv[])
{
 cout << "sizeof(C10): " << sizeof(C10) << endl;
 cout << "sizeof(C11): " << sizeof(C11) << endl;
 cout << "sizeof(C12): " << sizeof(C12) << endl;
 return 0;
}
输出为:
sizeof(C10): 8
sizeof(C11): 12
sizeof(C12): 16
The sizeof class C10 is affeced by one factor: bit padding.
sizeof(int) is 4 bytes, sizeof(char) is 1 bytes, in order to make the sizeof(C10) % (machine word) == 0,
so we have to make C10 occupies additional 3 bytes in the memory.
So does the class C11 and C12.
But there is a little special case for the latter two classes, why doesn’t the child class make use of its parent’s padding space?
for example, we can organize the memory space like this:
{C10(sizeof(int) + sizeof(char)) + C11(sizeof(char))} + (2 bytes padding)
 VS.
{C10(sizeof(int) + sizeof(char) + (3 bytes padding))} + {C11(sizeof(char) + (3 bytes padding))}
To clarify the answer, I will list a counter-example:
C11 * pC11 = new C11;
C12 * pC12_1 = pC11;
C12 * pC12_2 = new C12;
*pC12_2 = *pC12_1;// This assignment will leave the C12::val3 undefined.