面向对象
类的顺序,1.定义一个类(不占用存储空间)。2.实例化一个类的对象(创建一个只包含成员变量不包含成员函数的存储空间):(1)调用构造函数,如果没定义则为空。(2)按顺序执行成员定义。3.当对象作用域结束,调用析构函数。有相同作用域的对象,先构造先析构。
声明不占用存储空间,定义占用存储空间
例如void Box();//这是声明一个函数
void Box(){
}//这是定义一个函数。
1.类包括:成员变量和成员函数。
成员变量分为:public共有成员,private私有成员,protect保护成员,如果不加声明为private私有成员(结构体中不加声明为public共有成员)
访问 public protected private
同一个类 yes yes yes
派生类 yes yes no
外部的类 yes no no
2.
类内定义的函数默认为inline内置函数。
类的定义不占用内存空间,而实例化一个对象才创一个空间。
类实例化对象占有的存储空间:只包含成员变量部分,而不包含函数部分,如果创建多个对象,只有成员变量所占的存储空间加倍。
例如
class Time{
int hour;
int day;
int month;
void display(){
cout<<hour<<endl;
}
}//只占12个字节,不包含函数部分。如果创建10个对象,则一共占120个字节。
有个问题思考:既然所有的对象都拥有的是同一存储空间的成员函数,那该同一个函数怎么访问不同对象的成员变量呢?C++设定了指针this,用来指向不同的对象,当调用不同对象时,this就指向不同对象的成员变量。
3.构造函数
定义类时不能对成员变量赋值,因为类的定义不占用存储空间。
构造函数是在实例化对象时,首先创建一个对象,再调用构造函数,如果用户没定义,则系统自动调用一个空的构造函数。
构造函数和类名相同,不需要写返回值类型。
带参数的构造函数,对不同对象赋不同的初值:
Box(int a,int b,int c){ weight =a; hight =b; length =c; }
或者:
Box(int a,int b,int c):weight(a),height(b),length(c){}
构造函数的重载,重载是指定义多个同名的函数,但每个函数的参数类型和个数不同,在调用时提供的类型和个数不同,则调用不同的函数。
Box(int a=1,int b=2,int c=3);声明时指定默认参数 Box::Box(int a,int b,int c){//定义时不指定默认参数 weight =a; hight =b; length =c; } 或者Box::Box(int a,int b,int c):weight(a),height(b),length(c){}
要注意,默认参数构造函数和构造函数重载在一起容易报错,因为调用语句都是一样的,会出现歧义。
4.析构函数
释放内存前的一系列清理工作
5.对象数组
Box box[2]{ Box(1,2,3); Box(2,3,4); }
6.对象指针
Box *p; Box box; p = &box; //调用方式 (*p).weight; p->weight;
7.this指针:
当调用box.get()时,就将box的首地址赋值给了this指针,所以同一类的多个对象调用同一个函数时,根据不同this指针指向的地址,去访问不同对象的成员变量。
8.对象赋值,和复制对象
Box box2 = box1;//赋值是将box1的值给box2,其中的成员变量一一赋值,而复制是从无到有,调用复制构造函数,创建一个新的对象。复制还有种写法Box box2(box1);
9.静态成员
使得多个对象之间共享个数据,而不用全局对象,可以用静态数据成员。静态成员在声明类的时候,就分配了存储空间。而其他成员在声明类的时候不占内存空间。
要在类外初始化。int Box::height = 10;
作用域只有该类的作用域,而全局变量作用域是本文件或所有。
10.静态成员函数
如果静态成员关键字是私有的,则只能通过静态成员函数进行访问,所以静态成员函数的作用只是访问静态成员变量,并且静态成员函数不能访问非静态成员,因为属于的是类而不是对象,所以没有this指针。
11.类模板
如果两个类结构都一样,只是里面的成员变量的类型不一样,可以用类模板作为类型。
定义:template < class numtype >
用法:compare < int > cmp(4,7)//compare是类名,<>要告诉模板,输入数据的类型是什么来代替numtype,cmp是实例化的对象名。
template <class numtype> class Compare{ public: Compare(numtype a,numtype b){ x=a;y=b; } numtype max(){ return (x>y)?x:y; } private: numtype x,y; } //如果在类外定义的话 numtype Compare<numtype>::max(){ }
12.运算符重载:
#include "iostream" #include "algorithm" #include "vector" using namespace std; class Complex{ public: Complex(){real=0;image=0;} Complex(double r,double i){real=r;image=i;} Complex operator +(Complex &c2); void display(); private: double real; double image;; }; Complex Complex::operator +(Complex &c2){ Complex c; c.real = real + c2.real; c.image = image + c2.image; return c; } void Complex::display(){ cout<<real<<image<<'i'<<endl; } int main(){ Complex c1(3,4),c2(5,-10),c3; c3 = c1+c2; cout<<"c1+c2=";c3.display(); return 0; }
几个规则:有几个运算符不能重载 ,只能在C++已经有的运算符上修改,能有默认参数,而且参数中必须有一个类参数。
13.构造函数:
默认构造函数。Complex();
用于初始化的带参数的构造函数。Complex(double r,double i);
用于对象复制的复制构造函数。Complex(Complex &c);
转换构造函数。Complex(double r){real=r;image=0;}将一个其他类型的数据转换成一个对象。
类型转换函数。operator double(){return real;}将一个对象转换成另一个类型的数据。
14.继承
公有继承,不改变个成员访问属性。
私有继承,全变为私有。
保护继承,私有不变,其它变成保护成员。
- 面向对象六大设计原则(二)开闭原则
- 面向对象程序设计的基本特点
- JavaScript面向对象程序设计(5): 类
- 用C写有面向对象特点的程序
- 面向接口、对象、方面编程区别 -- 精简版
- 廖雪峰Python教程阅读笔记——7. 面向对象高级编程
- 面向对象和面向过程的区别
- java面向对象基本特征:封装、继承、多态
- [.net 面向对象程序设计进阶] (4) 正则表达式 (三) 表达式助手
- js面向对象实现图片轮播插件
- Java面向对象_3
- 深入Java面向对象预备篇(3.研究数组)
- 面向对象实现简单版的超级马里奥
- 初识面向对象
- 做一个饲养员给动物喂食物的例子体现JAVA中的面向对象思想,接口(抽象类)的用处
- 面向对象
- 廖雪峰python学习笔记8:面向对象初步
- 【面向对象设计】OOD原则
- 面向对象设计(OOD)的原则
- 黑马程序员——OC基础---面向对象语法