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,不需要通过类对象来调用(并不是说不能!)
- Cpp_类和对象
- Cpp_继承&对象模型
- Cpp_类的定义与实现
- Cpp_引用
- Cpp_继承
- Cpp_多态
- Cpp_链表
- Cpp_函数重载
- Cpp_函数缺省参数
- Cpp_内联函数
- Cpp_动态内存分配
- Cpp_类型转换
- Cpp_构造函数
- Cpp_析构函数
- Cpp_静态成员
- Cpp_成员指针
- Cpp_操作符重载
- Cpp_异常处理
- hdu1071 The area
- 近200篇机器学习&深度学习资料分享
- hdu 1518 square
- Uva The Tower of Babylon
- Started Service 与 Bound Service
- Cpp_类和对象
- C# 5.0 使用任务调试表TaskScheduler来运行task
- UVA 540(p117)----Team Queue
- 在CentOS上MySQL数据库服务器配置方法
- BZOJ-2748 音量调节 DP+背包(脑残)
- APP引导页Demo
- UVA 548(p155)----Tree
- 嵌入式的一些面试问题
- JS下实现加号减号的数量加一减一