1.0 封裝後的佈局成本

1.0.1    C語言中(.c)ios

1.    數據和函數是分開聲明的,語言自己沒有支持「數據和函數」之間的關聯性。算法

2.    這種程序方法爲程序性的,由一組「分佈在各個以功能爲導向的函數中」的算法驅動,處理共同的外部數據。函數

3.    例子佈局

typedef struct _point
{
    int x;
    int y;
}Point;

// 定義一個函數
void Point_Print(const Point *pd)
{
    printf("%d, %d", pd->x, pd-y);
}

// 效率更高些的作法
#define POINT_PRINT(pd) \
    printf("%d, %d", pd->x, pd-y);
    
// 前置處理宏
#define SET_VAL(p, xVal) (p.x) = (xVal);


1.0.2    C++語言中(.cpp)spa

template <class type, int dim>
class CPoint
{
public:
    CPoint() {}
    
    CPoint(type coords[dim])
    {
        for (int idx = 0; idx < dim; idx++)
        {
            m_coords[idx] = coords[idx];
        }
    }
    
    type& operator[] (int idx)
    {
        assert(idx < dim && idx >= 0);
        
        return m_coords[idx];
    }
private:
    type m_coords[dim];
};


1.0.3    C和C++的比較3d

1.    「一個 ADT 或 class hierarchy 的數據封裝」比「C程序中程序性地使用全局數據」好。code

2.    class CPoint 沒有增長佈局成本。繼承

3.    數據成員和 C 結構體同樣,成員函數在class聲明中,但不在 object 中。it

4.    非內聯成員函數只有一個函數實體,而內聯成員函數會在使用者上產生一個函數實體。io

5.    C++ 在佈局和存取時間上的主要額外負擔,是由 virtual 引發的,包括:

a.    virtual function,用以支持一個有效率的「執行期綁定」。

b.    virtual base class,用以實現「屢次出如今繼承體系中的 base class,有一個單一而被共享的實體」。

c.    多重繼承下的額外負擔,derived class 和其第二,或後繼之 base class 的轉換。


1.0.4    完整的代碼

  1. .h文件

#ifndef _PROJ10_PROJ10_proj10_
#define _PROJ10_PROJ10_proj10_

//#define C_BETA
//#define CPP_BETA_1
//#define CPP_BETA_2
//#define CPP_BETA_3

/**************************************************************/
#ifdef C_BETA
#include <stdio.h>

typedef struct _point3d
{
    float x;
    float y;
    float z;
}Point3d;

#define X(pt, _x) (pt.x) = (float)(_x);
#define Y(pt, _y) (pt.y) = (float)(_y);
#define Z(pt, _z) (pt.z) = (float)(_z);

#define POINT3D_PRINT(pt) \
    printf("(%f, %f, %f)\n", pt.x, pt.y, pt.z);

void Point3d_Print(const Point3d& pt3d)
{
    printf("(%f, %f, %f)\n", pt3d.x, pt3d.y, pt3d.z);
}
#endif // C_BETA
/**************************************************************/

/**************************************************************/
#ifdef CPP_BETA_1
#include <iostream>

class CPoint3d
{
    friend std::ostream& operator<< (std::ostream& os, const CPoint3d& pt);

public:
    CPoint3d(const float& x = 0.0, const float& y = 0.0, const float&z = 0.0)
    {
        m_x = x;
        m_y = y;
        m_z = z;
    }
    
    ~CPoint3d(void) {}
    
    void x(const float& x) { m_x = x; }
    void y(const float& y) { m_y = y; }
    void z(const float& z) { m_z = z; }
    
    float x(void) const { return m_x; }
    float y(void) const { return m_y; }
    float z(void) const { return m_z; }

private:
    float m_x;
    float m_y;
    float m_z;
};

inline std::ostream& operator<< (std::ostream& os, const CPoint3d& pt)
{
    os << "(" << pt.x() << ", " << pt.y() << ", " << pt.z() << ")" << std::endl;
    
    return os;
};

#endif // CPP_BETA_1
/**************************************************************/

/**************************************************************/
// 座標類型參數化
#ifdef CPP_BETA_2
#include <iostream>

template <class type>
class CPoint3d;

template <class type>
std::ostream& operator<< (std::ostream& os, const CPoint3d<type>& pt);

template <class type>
class CPoint3d
{
    friend std::ostream& operator<< <type>(std::ostream& os, const CPoint3d<type>& pt);

public:
    CPoint3d(const type& x = 0.0, const type& y = 0.0, const type&z = 0.0)
    {
        m_x = x;
        m_y = y;
        m_z = z;
    }
    
    ~CPoint3d(void) {}
    
    void x(const type& x) { m_x = x; }
    void y(const type& y) { m_y = y; }
    void z(const type& z) { m_z = z; }
    
    type x(void) const { return m_x; }
    type y(void) const { return m_y; }
    type z(void) const { return m_z; }

private:
    type m_x;
    type m_y;
    type m_z;
};

template <class type>
std::ostream& operator<< (std::ostream& os, const CPoint3d<type>& pt)
{
    os << "(" << pt.x() << ", " << pt.y() << ", " << pt.z() << ")" << std::endl;
    
    return os;
};

#endif // CPP_BETA_2
/**************************************************************/

/**************************************************************/
// 座標類型和座標數目都參數化
#ifdef CPP_BETA_3
#include <assert.h>
#include <iostream>

template <class type, int dim>
class CPoint3d;

template <class type, int dim>
std::ostream& operator<< (std::ostream& os, const CPoint3d<type, dim>& pt);

template <class type, int dim>
class CPoint3d
{
    friend std::ostream& operator<< <type, dim>(std::ostream& os, const CPoint3d<type, dim>& pt);

public:
    CPoint3d(void) 
    {
        for (int i = 0; i < dim; ++i)
        {
            m_coords[i] = 0;
        }
    }
    
    CPoint3d(type coords[dim])
    {
        for (int i = 0; i < dim; ++i)
        {
            m_coords[i] = coords[i];
        }
    }

    ~CPoint3d(void) {}
    
    inline type& operator[] (const int& idx)
    {
        assert(idx < dim && idx >= 0);
        return m_coords[idx];
    }
    
    inline type operator[] (const int& idx) const
    {
        assert(idx < dim && idx >= 0);
        return m_coords[idx];
    }

private:
    type m_coords[dim];
};

template <class type, int dim>
std::ostream& operator<< (std::ostream& os, const CPoint3d<type, dim>& pt)
{
    os << "(";
    
    for (int i = 0; i < dim - 1; ++i)
    {
        os << pt[i] << ", ";
    }
    
    os << pt[dim - 1] << ")" << std::endl;
    
    return os;
};

#endif // CPP_BETA_3
/**************************************************************/

#endif //_PROJ10_PROJ10_proj10_


2.    .cpp文件

#include "proj1.0.h"

int main(void)
{
#ifdef C_BETA
    Point3d pt;
    pt.x = 1.0;
    pt.y = 2.0;
    pt.z = 3.0;
    
    printf("(%f, %f, %f)\n", pt.x, pt.y, pt.z);
    Point3d_Print(pt);
    POINT3D_PRINT(pt);
    
    X(pt, 1.1);
    Y(pt, 2.1);
    Z(pt, 3.1);
#endif // C_BETA
	
#ifdef CPP_BETA_1
    CPoint3d pt;
    std::cout << pt;
#endif // CPP_BETA_1

#ifdef CPP_BETA_2
    CPoint3d<int> pt;
    std::cout << pt;
#endif // CPP_BETA_2

#ifdef CPP_BETA_3
    CPoint3d<int, 2> pt;
    std::cout << pt;
#endif // CPP_BETA_3

    return 0;
}
相關文章
相關標籤/搜索