【深入探索C++对象模型】(1)关于对象

在C语言中,数据和函数(操作数据的方法)是没有关联机制的,它们被分开声明和使用,这样的语言叫做“程序性语言”,由一组分布在各个以功能为导向的算法所驱动,各个函数处理共同的外部数据。

例如,定义一个结构体

typedef struct Point {

    int x;

    int y;

}Point2d;

当需要对这个结构体对象进行处理时,就需要定义一个函数:

void print_point(const Point2d &pt) {

    printf("(%d, %d)", pt.x, pt.y);

}

或者更高效地,定义一个宏:

#define PRINT_POINT(pt) printf("(%d, %d)", pt.x, pt.y);

当需要对其进行修改,就需要这样做:

Point2d pt;

pt.x = 1;

pt.y = 2;

到了C++这里,class机制可以允许你用独立的“抽象数据类型”来实现一个Point2d:

class Point2d{

public:

    Point2d(int x, int y) : x_(x), y_(y) { }

    int x() const {return x_; }

    int y() const {return y_; }

    void setX(int x) {x_ = x; }

    void setY(int y) {y_ = y; }

private:

    int x_;

    int y_;
};


inline ostream & operator << (ostream &os, const Point2d &pt) {

    os << "(" << pt.x() << ", " << pt.y() << ")";

}

更具有通用性的,定义一组继承关系的类,可以抽象出一维、二维和三维点:

class Point {

public:

    Point(int x) : x_(x) { }

    int x() const {return x_; }

    void setX(int x) {x_ = x; }

protected:

    int x_;

}

class Point2d : public Point{

public:

    Point2d(int x, int y) : Point(x), y_(y) { }

    int y() const {return y_; }

    void setY(int y) {y_ = y; }

protected:

    int y_;
};

class Point3d : public Point2d {

public:

    Point3d(int x, int y, int z) : Point2d(x, y), z_(z) { }

    int z() const {return z_; }

    void setZ(int z) {z_ = z; }

protected:

    int z_;
};

更通用的,使用模板类实现参数抽象化:

template <class T>

class Point3d : public Point2d {

public:

    Point3d(T x, T y, T z) : x_(x), y_(y), z_(z) { }
 
    T x() const {return x_; }
    T y() const {return y_; }
    T z() const {return z_; }

    void setX(T x) {x_ = x; }
    void setY(T y) {y_ = y; }
    void setZ(T z) {z_ = z; }

protected:
    T x_;
    T y_;
    T z_;
};

可见,C++和C,不仅仅在程序的风格上截然不同,在变成的思想上也是有明显的差异:C++旨在实现事务“抽象”,更通用性能更庞大,C语言的优势在于精简(相对C++而言)。

很难说,要定义一个点,上述的使用C语言和C++来实现哪一种更可取,或者哪一种更好、更强!

加上封装以后的空间成本

 上述例子中,C++对Point2d的操作方式(在类中定义了一些方法),相对于C的结构体机制来说,增加了多少空间成本呢?答案是:没有增加任何的空间成本!数据成员(data member)直接内含在每一个类对象中,这和C结构体是一样的。至于成员函数,虽然被声明在类的定义中,但是却没有出现在任何一个类对象中,每一个非内联的成员函数(注意必须是非内联)只会产生一个函数实体。

造成空间成本的情况

C++在这两种情况下才会造成额外的空间负担:

  • 虚函数:执行期绑定的高效机制,实现C++的多态性
  • 虚基类:多次出现在继承体系中,但是只保留一份共享实体的机制。

除此以外,在没有充分的理由来说C++比C更庞大或臃肿。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章