Inside The C++ Object
1. 关于对象
1.1 一个抽象数据类型(ADT)Point3d:
templat <class type>
class Point3d
{
public:
Point3d(type x = 0, type y = 0, type z = 0)
: _x(x), _y(y), _z(z) {}
type x() { return _x; }
type y() { return _y; }
type z() { return _z; }
void x(type xval) { _x = xval; }
private:
type _x;
type _y;
type _z;
};
inline template<class type>
ostream&
operator<<( ostream &os, const Point3d &pt)
{
os << "(" << pt.x() << ", " << pt.y()
<< ", " << pt.z() << ")";
};
1.2 pointer和reference
不管是pointer或reference都只需一个word的空间。
// class Bear : public ZooAnimal{...};
Bear b("Yogi");
// pb、rb都指向b的地址,包含整个Bear object
Bear *pb = &b;
Bear &rb = *pb;
// pz涵盖的地址只包含Bear object中的ZooAnimal subobject
// 除了subobject中的members,不能使用pz来直接处理Bear
// 的members
ZooAnimal *pz = &b;
// 但是,可以通过显式的downcast操作
(static_cast<Bear*>(pz))->cell_block;
// 或是下面这样
if (Bear* pb2 = dynamic_cast<Bear*>(pz))
pb2->cell_block;
2 构造函数语意学
2.1 Default Constructor的构造操作
下列4种情况,会造成“编译器必须为未声明constructor的classes合成一个nontrivial default constructor”:
- “带有default constructor”的member class object
// 编译器为class Bar合成一个default constructor
class Foo { public : Foo(), Foo(int) ...};
class Bar { public : Foo foo; char *str;}; // 不是继承,是内含
- “带有default constructor”的Base class
// 编译器为Bear合成一个default constructor
class ZooAnimal {public: ZooAnimal(), ...};
class Bear : public ZooAnimal {...};
- 带有一个virtual function的class
- 带有一个virtual base class 的class
class X {public: int i;};
class A : public virtual X {public: int j;};
2.2 Copy Constructor的构造操作
class X {...};
X x;
// 显式地以一个object内容作为另一个object的初值
X x1 = x;
X x2(x);
X x3 = X(x);
// object作为函数返回值
X foo(){
X xx;
// ...
return xx;
}
// 显式定义一个copy constructor
X::X( const X &x );
// 使用C++库的memcpy()实现copy constructor
// ps: classes不含任何由编译器产生的内部members(无virtual)
Point3d::Point3d(const Point3d &rhs)
{
memcpy(this, &rhs, sizeof(Point3d));
};
2.4 成员初始列表化
4种使用情况:
- 当初始化一个reference member;
- 当初始化一个const member;
- 当调用一个base class的constructor,而它拥有一组参数时;
- 当调用一个member class的constructor,而它拥有一组参数时;
// 坚持这种编码风格
// 注意:
// 1.list中的顺序是由class中members声明顺序决定的,而非初始化列表中的顺序
// 先初始化_name,再初始化_cnt
class Word {String _name; int _cnt;}
Word::Word() : _cnt(0), _name(0) {}
// 2. 列表初始化先于explicit user code