C++ uses ADT(abstract data type)
class Point3d
{
public:
Point3d(float x=0.0,float y=0.0,float z=0.0):_x(x),_y(y),_z(z){}
float x() {return _x;}
float y() {return _y;}
float z() {return _z;}
private:
float _x;
float _y;
float _z;
}
inline ostream& operator << (ostream &os, const Point3d &3d)
{
os << pt.x() << pt.y() << pt.z();
}
Data and function are saperately handled in C, it is a procedural programming.
typedef struct point3d
{
float x;
float y;
float z;
} Point3d;
#define POINT3D_PRINT(pd) printf("%g, %g, %g", pd->x, pd->y, pd->z);
1. Layout cost for adding encapsulation
- data member is inside class object like it is in C struct
- member functions are outside class object - only one member function instance will be created for each non-inline member function. Everytime, a function instance will be created for the client of inline function.
Additional costs (on space or time) is from:
- virtual function mechanism to support runtime binding
- virtual base class to implement one single shared instance of base class which appers more than once
2. The C++ Object Model
class data member
- static - saved outside class object
- nonstatic - saved in each class object
class function member:
- static - outside class object
- nonstatic - outside class object
- virtual
- Pointers to virtual functions of class are stored in virtual table - vtbl
- A pointer to vtbl is stored in class object - vptr
- vptr is set and reset by class automatically
- type_info (to support RTTI) object is referenced by vtbl (1st slot of vtbl)
- no vptr/vtbl will be produced if there is no virtual function
class X
{
public:
virtual void foo();
};
X xx;
X *xPtr = new X;
xx.foo();
// no virtual mechanism
// will be converted into
foo(&xx);
xPtr->foo();
// virtual mechanism is activated
// will be converted into
(*xPtr->vptr[2])(xPtr);
3. A keyword distinction
When should we use struct in C++ instead of class?
We can use struct whenever/wherever we want to and then declare private/protected/public and virtual functions...
4. An object distinction
3 programming paradigms:
- procedural model
- abstract data type model, ADT
- object-oriented model
take care when doing polymorphism, use pointer or reference to achieve polymorhism in C++, otherwise an certain object have certain behaviour
Library_materials thing1;
class Book: public Library_materials {}
Book book;
thing1 = book; // book is sliced!
thing1.checkin(); // calling checkin() in base class Libarary_material
Library_materials &thing2 = book; // thing2 is referenced to book
thing2.checkin(); // calling checkin() in Book class
C++ uses following methods to support polymorphism (runtime):
- implicit convertion, using a public base class to point to a derived class
- use virtual function mechanism
- use dynamic_cast or typeid operaton
the size of an class object
- sum size of all nonstatic data member
- padding space due to requirement of alignment
- any additional overhead to support virtual mechanism
- a int type pointer pointing to address 1000, if it is a 32-bit machine, will cover address space 1000-1003 (4-bytes for a int type pointer on 32-bit machine)
- string name - 8-bytes
- int loc - 4-bytes
- vptr - 4-bytes
- void* pointer can only handle 1 address, so it cannot handle the object it points to
after adding polymorphism
- Dances dances_known - 4-bytes
- int cell_block - 4-bytes
Bear b;
ZooAnimal *pz = &b;
Bear *pb = &b;
Both pz and pb point to the first byte of Bear object, the difference is pb covers all the bear object, pz only covers the subobject ZooAnimal inside Bear object.
Why a pointer or a reference can support multimorphism?
A pointer or a reference will not trigger any type-dependent commitment, the only thing will changed is the size and explaination of a certain memory it points to.