您的位置:首页 > 编程语言 > C语言/C++

《C++程序设计》笔记之-基于对象程序设计

2013-09-07 00:12 218 查看
面向对象:除主函数被操作系统调用外,其它函数可以相互调用,面向一个个函数。 程序 = 数据结构 + 算法

基于对象:以类为基本单位构成的程序

面向对象:抽象、封装、继承、多态 对象 = 数据结构 + 算法 程序 = (对象 + 对象 + 。。。)+消息

如果类中定义既不指定private,也不指定public,默认为private ,

protected:不能被类外(即类体,类的对象属于类外)访问,但能被派生类成员函数访问

定义:可以不出现类名,直接定义,合法,但少用(类的申明和使用分开,并不只为一个程序服务,一般放在类库中)

class

{

。。。

}stu1,stu2;

成员函数:一般定义为public,为类的对外接口。成员函数可以访问类中所有成员(public的和private的.)

类体定义应在函数定义之前,否则编译出错。

内置成员函数(内置函数):一般规模较小,调用频率高,程序调用它时并不真正执行函数调用过程(如保留返回地址等处理),而是把函数代码嵌入程序调用点,大大减小调用成员函数时间开销。 用 inline 申明(类体内定义成员函数可省略inline,默认为内置的)

若在类体外定义inline函数,则应将它与类体放在同一源文件中,否则编译无法进行置换(将函数代码拷贝到函数调用点)

缺点:不利于类的接口与类的实现分离,不利于信息隐蔽,

成员函数存储方式:每个对象所占用的存储空间只是改对象数据成员所占存储空间,各对象公用一段成员函数代码(包括inline函数),用this指针区分(也共用一份静态数据成员)

类外不能访问私有成员,如stu1.num = 1010; (若num申明为private,则此复制语句错误)

类的申明和实现(成员函数定义)放在不同文件中,这样成员函数只需编译一次,将形成的目标文件保存起来,需要时再与程序目标文件连接(类似于库函数)

C++程序员不习惯将所有申明写在开头,有别于C语言

对象初始化:

若一个类的所有成员都是public的,则在定义对象时可以进行初始化。(此时与结构体初始化类似)

用构造函数初始化:(不需用户调用,建立对象时自动执行)。名字与类名相同,无类型(不是void型),不返回任何值,一般为public,只能执行一次

用一个类对象初始化另一个类对象

Time t1 = t2, 把t2各数据成员值复制到t1对应成员,而不调用t1的构造函数

带参数的构造函数:Box::Box(int h, int w, int len )

{

......

}

或参数初始化表: Box(int h, int w, int len):height(h),width(w),length(len){ } //后面无分号

若数据成员为数组,则必须在构造函数体内对其赋值,而不能在参数初始化表内对其初始化

Student(int n,char s, char nam[]):num(n),sex(s){strcpy(name,nam);}

构造函数重载:具有相同名字,参数个数或类型不同

无参构造函数属于默认构造函数,一个类只有一个

使用默认参数的构造函数: Box(int h =10, int w = 10, int len =10); //类体内申明,指定默认参数

Box::Box(int h, int w, int len ) //类体外定义

{

......

} //此时即使定义对象时实参不全或没有,也会使用默认值

一般不应同时使用构造函数重载和有默认参数的构造函数,很容易冲突

析构函数:并不是删除对象,而是在撤销对象占用内存前执行一些清理工作。

1、自动局部对象:当函数调用结束时对象释放,释放前自动执行析构函数

2、static局部对象:函数结束时对象不释放,等到main函数结束或调用exit结束程序时,调用static对象析构函数

3、全局对象:程序离开其作用域时(如main函数结束)调用其析构函数

由于析构函数没有类型,没有参数,所以不能重载,一个类只有一个析构函数

调用析构函数顺序:一般与调用构造函数顺序相反(相当于栈)(对同一类存储类别对象而言的,static或者自动的)

对象数组: Box a[3] =

{

Box(1,2,3),

Box(4,5,6),

Box(7,8,9),

};

指向对象成员函数的指针: 以下3点必须匹配:1、函数参数类型和参数个数 2、函数返回值 3、所属的类

void (Time::*p)(); //和C语言相比多了类名,即第三条约束

p = &Time::get_time; 此时p指向public成员函数get_time的入口地址 get_time不需要参数,只是函数名

This指针,隐式调用

对象调用函数 Box1.volume();

相当于: Box1.volume(&volume);

公用数据对象的保护:

常对象:必须要有初值,所有数据成员值不能修改 Time const t1(1,2,3); 或者const Time t1(1,2,3);

常对象只能调用其常成员函数(除系统自动调用的隐式的构造函数和析构函数)即常成员函数是其唯一对外接口

常成员函数只能访问常对象数据成员,不能修改。但若将数据成员申明为mutable,就可以用常成员函数修改它

对于一般的类:

常成员函数只能引用本类中的数据成员,不能修改。

申明:void get_time()const; //const在后, 申明和定义时都要加const,调用时不必加

非const成员函数可以访问const数据成员,但常对象不能调用非const成员函数

对象的动态建立和释放:

静态定义的对象,在程序运行过程中,对象所占空间不能释放,直到函数结束

动态建立对象:需要时建立,不需要时随时撤销,提高内存利用率

用new建立的对象一般不用对象名,用指针访问

Box *p = new Box(1,2,3,); 返回对象在内存中的首地址

对象的赋值: 类的数据成员中不能包括动态分配的数据,否则在赋值时出现严重后果

原因:如果某个类的对象a里面有动态申请的数据,当你把a直接复制给同一个类的对象b的时候,a中的动态指针也给了b,这样a,b中的指针指向同一块内存.这样无论a或者b释放内存都会导致另外一个访内违例崩溃.
解决这个问题需要自己重载赋值运算符和拷贝构造函数.如果不想重载,并且也不喜欢出现错误,那么就把这两类函数声明为私有。
对象的复制:Box Box2(Box1);用已有的类Box1克隆出Box2
在建立对象时调用一个特殊构造函数:复制(拷贝)构造函数,其只有一个参数,为本类对象,
Box::Box(const Box &b)
{
height = b.heigt;   width = b.width;  length = b.len;
}
静态数据成员:在同类多个对象间实现共享,在内存中只占用一份空间
即使不定义对象,也为静态数据成员分配空间,能被引用(通过类名) Box::height
不随对象撤销而释放,程序结束时才释放空间
可以初始化,但只能在类体外:默认为0
int Box::heigth = 10;
不能用参数初始化表对静态成员初始化。
静态成员函数:不是为了对象之间的沟通,而是为了处理静态数据成员
静态成员函数不属于哪个对象,没有this指针,无法对某个对象中的非静态数据成员访问
公用成员函数对本对象中的静态和非静态数据成员都能访问
友元函数:可以访问本类私有成员
Date类体里申明:   	friend void display(Date &);
friend void Time::display(Date &);
友元类:里面所有函数都是其友元函数          友元关系为单向,且不能传递
友元类不利于信息屏蔽,一般不把一个类申明为友元类,但有利于数据共享   (两者中选择平衡点)
类模板:
template <class numtype>   //numtype为虚拟类型名,一般为一个数据类型
类模板包括类型参数(参数化的类)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐