【深入探索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更龐大或臃腫。

 

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