Cpp_类和对象

来源:互联网 发布:java中如何处理高并发 编辑:程序博客网 时间:2024/06/08 11:25

围绕具体问题对属性和行为进行有意识的选择,使复杂的具体问题得到简化——面向对象的程序设计

类的定义与实例化

1.类的一般形式

class/struct 类名 : 继承方式 基类, … {
访问控制限定符:
类名 (形参表) : 成员变量 (初值), … { // 构造函数
函数体;
}
~类名 (void) { // 析构函数
函数体;
}
返回类型 函数名 (形参表) 常属性 异常说明 { // 成员函数
函数体;
}
数据类型 变量名; // 成员变量
};

2.访问控制限定符

  • 公有成员——public:谁都可以访问。

  • 私有成员——private:只有该类自己的成员函数可以访问。

  • 保护成员——protected:只有该类及其子类的成员函数可以访问。

3.成员函数

C++支持三种类型的成员函数,static,nonstatic和virtual,每一种成员函数被调用的方式都不同。
3.1nonstatic成员函数
原始的”C-withClass”只支持nonstatic成员函数
C++的设计准则是nonstatic member function至少需要和非成员函数具有相同的执行效率。
编译器实际上将成员函数内化为非成员函数

在这里举一个例子
假设有类的成员函数

float Point3D::magnitude3d()const{    return sqrt(_x*_x + _y*_y + _z*_z);}

转化为非成员函数的过程大概需要经过以下几个步骤

1)首先改写函数原型,将一个额外的参数安插到成员函数中,用来提供一个存取的管道,该额外的参数被称为this指针

float Point3D::magnitude3d(Point *const this)const{return sqrt(_x*_x + _y*_y + _z*_z);}

2)在函数体内对成员数据的存取通过this指针来完成

float Point3D::magnitude3d(Point *const this)const{    return sqrt(this->_x*this->_x + this->_y*this->_y + this->_z*this->_z);}

3) 最后讲成员函数重写为外部的一个函数,对其函数名进行”mangling”处理,使其称为独一无二的标识。

extern magnitude_7Ponint3dFv(register Point3d *const this);
Tips:mangling处理规则:一般成员名前面加上类名会形成独一无二的名称,不过再加上参数列表就会确保名称这时会是独一无二的了

这时,成员函数已经转化好了,而我们的代码中通过对象对其进行的每次调用,这时也需要有形式上的改变。

obj.magnitude();    ⇒   magnitude_7Ponint3dFv(&obj);ptr->magnitude();   ⇒   magnitude_7Ponint3dFv(ptr);
void normalize_7Ponint3dFv(register Point3d *const this,Point3d &_result){    register float mag = this->magnitude();    _result.Point3d::Point3d(this->_x/mag,this->_y/mag,this->_y/mag) ;  //假设Point3d的copy constructor已经声明好了      return;}

Virtual Member Function

若normalize函数是一个虚函数,它会经历如下的内部转换

ptr->normalize();   ⇒  (*ptr->vptr[1])(ptr);

其中vptr是由编译器生成的虚表指针,实际上vptr的名字也会被mangled

而此时如果magnitude函数也是一个虚函数,则它在normalize函数中的调用操作将会被转化为如下的形式

register float mag = magnitude();  ⇒  register float mag = (*this->vptr[2])(this);

这里要说明一下,由于magnitude在normalize中调用,而后者已经已经由虚拟机制resloved(具体的对象已经确定,不必再通过虚指针来进行),所以明确地调用Ponint3d实体会比较由效率

register float mag = Point3d::magnitude();

magnitude函数声明为inline函数会更有效率,使用类的域解析符::调用一个virtual函数,其resolved方式会和nonstatic 成员函数一样。

经由类对象调用的虚函数(注意这里说的并不是基类对象的指针)这种操作应该总是被编译器对待一般的nonstatic 成员函数一样地resolved
像是这样:

Point3d obj;obj.normalize(); =>   normalize_7Point3dFv(&obj);

Static Member Function

若normalize函数是一个静态成员函数,其调用操作会转化为对一个nonmember function的调用

在引入静态成员函数之前,C++要求语言要求所有的成员函数都要经过对象来调用,但是如果这个成员函数中没有对成员进行存取,也就不需要this指针,这样也就没有必要通过类的对象来调用成员函数。

所以当时出现了这样一种写法:

((Point3d *)0)->object_count(); //函数object_count()函数只是简单地传回一个static data member

上面的调用接着会被转化为object_count((Point3d *)0)
把0强制转化为类的指针,因而也就会提供出了一个this指针,之所以把0强转,是因为这个this指针根本用不到!!!

当之后推出了static member function之后,它的最主要的特性就是没有this指针,所以也就不能直接存取类中的非静态成员,也不能被声明为const,volatile或者virtual,不需要通过类对象来调用(并不是说不能!)

0 0
原创粉丝点击