1.0.1 C语言中(.c)
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)
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++的比较
1. “一个 ADT 或 class hierarchy 的数据封装”比“C程序中程序性地使用全局数据”好。
2. class CPoint 没有增加布局成本。
3. 数据成员和 C 结构体一样,成员函数在class声明中,但不在 object 中。
4. 非内联成员函数只有一个函数实体,而内联成员函数会在使用者上产生一个函数实体。
5. C++ 在布局和存取时间上的主要额外负担,是由 virtual 引起的,包括:
a. virtual function,用以支持一个有效率的“执行期绑定”。
b. virtual base class,用以实现“多次出现在继承体系中的 base class,有一个单一而被共享的实体”。
c. 多重继承下的额外负担,derived class 和其第二,或后继之 base class 的转换。
1.0.4 完整的代码
.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;
}