期末复习笔记
期末又来啦,是时候整理一下笔记,准备期末考试吧!
一 类与对象
1 构造函数(特殊的成员函数)
1)为对象分配空间
2)为对象的数据成员进行初始化
3)其他指定的任务
例如:
#include<iostream>
using namespace std;
class Date{
private:int year;
int month;
int day;
public:Date(int y,int m,int d);//声明构造函数原型
void showdate();
};
Date::Date(int y,int m,int d)//定义构造函数
{ year=y;
month=m;
day=d;
}
void Date::showdate()
{
cout<<year<<"."<<month<<"."<<day<<endl;
}
int main()
{
Date obj(1995,7,5); //采用构造函数进行初始化的方式一
obj.showdate();
//Date *ptr=new Date(1995,7,5); //初始化方式二
//ptr->showdate();
return 0;
}
注:1与类名要相同
2没有返回值,即时是void也不行
3可定义在类内或类外
4一般声明为公有成员
5可以不带参数
6 在一个类中定义了全部是默认参数的构造函数后, 不能同时再声明无参数的默认构造函数,或其他重载构造函数,避免产生二义性
2 初始化列表
带有成员初始化列表的构造函数的一般形式如下:
类名::构造函数名([参数表])[:(成员初始化列表)]
{
构造函数体
}
成员初始化列表的一般形式为:
数据成员名1(初始值1),数据成员名2(初始值2),…
说明:
(1)在C++中某些类型的成员是不允许在构造函数中用赋值语句直接赋值的。例如, 对于用const修饰的数据成员,或是引用类型的数据成员,是不允许用赋值语句直接赋值的。因此,只能用成员初始化列表对其进行初始化。
(2)数据成员是按照它们在类中声明的顺序进行初始化的,与它们在成员初始化列表中列出的顺序无关
3 析构函数
1)特点
1 与类名相同,带有~
2 不返回任何值
3没有参数,不能被重载
4 撤销对象,系统自动调用
ps系统自动的三种情况
① 主程序main()运行结束。
② 如果一个对象被定义在一个函数体内,则当这个函数结束时,该对象的析构函数被自动调用。
③ 若一个对象是使用new运算符动态创建的,在使用delete运算符释放它时,delete会自动调用析构函数
4 拷贝构造函数(使用一个已经存在的对象去初始化新对象)
1)
自定义拷贝构造函数的一般形式如下:
类名::类名(const 类名 &对象名)---已经存在的对象
{
拷贝构造函数的函数体
}
2)特点
①该函数与类同名,并且不能指定返回值类型
②该函数只有一个参数,并且是同类对象的引用
③每个类必须有一个拷贝构造函数。
3)调用拷贝构造函数的情况
1 当用类的一个对象去初始化该类的另一个对象时
2 当函数的形参是类的对象, 在调用函数进行形参和实参结合时
3当函数的返回值是类的对象, 在函数调用完毕将返回值(对象)带回函数调用处时
5 对象数组
1 如果类中含有带有一个参数的构造函数,则定义对象数组时,可通过初始值表进行赋值;当各元素对象的初值要求为不同的值时,需要定义带参数(无默认值)的构造函数
当各个元素的初始值为相同的值时,可以在类中定义不带参数的构造函数或带有默认参数值的构造函数;
2 如果类中含有带有多个参数的构造函数,则定义对象数组时应当用带有多个参数的构造函数给对象数组赋值
6 对象指针(用于存放对象地址的指针变量)
7 向函数传递对象
1)使用对象指针作为函数参数 ,传址调用,函数中对形参对象成员的任何修改均影响调用该函数的实参对象本身
2)使用对象引用作为函数参数,传址调用,函数中对形参对象成员的任何修改均影响调用该函数的实参对象本身
优先选择对象引用!
8 静态成员
1 静态数据成员(为了实现同一个类的多个对象之间的数据共享)
#说明:
(1)静态数据成员属于类
用类名访问静态数据成员的格式如下:
类名::静态数据成员名
(2)静态数据成员初始化应在类外单独进行,而且应在定义对象之前进行。一般在主函数main 之前,类声明之后的特殊地带为它提供定义和初始化
静态数据成员初始化的格式如下:
数据类型 类名::静态数据成员名 = 初始值;
例如: int Student::count=0
(3)公有静态数据成员 可以在对象定义之前被访问。
一般格式: 类名::静态数据成员名
(4) 对象定义后,公有的静态数据成员,也可以通过对象进行访问。
一般格式:
对象.静态数据成员名
对象指针->静态数据成员名
例如: cout<<Stu1.count;
(5) 私有的静态数据成员不能被外界直接访问。必须通过公有的成员函数间接访问
(6) C++支持静态数据成员的一个主要原因是可以不必使用全局变量。
静态数据成员的主要用途是定义各个对象所公用的数据,如统计总数、平均数等。
2 静态成员函数(静态成员函数属于整个类,是该类所有对象共享的成员函数,而不属于类中的某个对象)
1)
定义静态成员函数的格式如下:
static 返回类型 静态成员函数名(参数表);
2)调用公有静态成员函数的一般格式有如下几种:
类名::静态成员函数名(实参表)
对象.静态成员函数名(实参表)
对象指针->静态成员函数名(实参表)
注:
静态成员函数需要访问非静态成员,静态成员函数只能通过对象名(对象指针或引用)访问该对象的非静态成员。
如把display()函数定义为静态成员函数:
static void display(small_cat& w)
{ cout <<"这只小猫的重量是 "<<
<<w.weight<<"千克 \n ";}
9 友元
1 友元函数(友元函数不是当前类的成员函数,既可以是非成员函数,也可以是另一个类的成员函数)
注:1)定义友元函数,形参是类Date的对象的引用
2)友元函数的声明可以放在公有部分,也可以放在保护部分和私有部分
3)因为友元函数不是类的成员,所以它不能直接调用对象成员,它必须通过对象(对象指针或对象引用)作为入口参数,来调用该对象的成员。
例如:void showDate(Date& d) { cout<<d.year<<"."<<d.month<<"."<<d.day<<endl;}
4) 一个函数可以是多个类的友元函数
例如:void showDate_Time (Date& d,Time& t)
{cout<<d.year<<"."<<d.month<<"."<<d.day<<endl;
cout<< t.hour <<":"<< t.minute <<":"<< t.sec <<endl;
}
2 友元成员函数(一个类的成员函数也可以作为另一个类的友元)
如:friend void Time::showDate_Time(Date&);
例子:
#include<iostream>
using namespace std;
class Date; //对Date类的提前引用声明
class Time{ //声明类Time
public:
Time (int h,int m,int s) //定义构造函数
{ hour =h; minute =m; sec =s;}
void showDate_Time(Date&);
private:
int hour; int minute; int sec; };
class Date{ //声明类Date
public:
Date(int y,int m,int d) //定义构造函数
{ year=y; month=m; day=d; }
friend void Time::showDate_Time(Date&);
private:
int year; int month; int day;};
void Time::showDate_Time (Date& d) {cout<<d.year<<"."<<d.month<<"."<<d.day<<endl;
cout<<hour<<":"<<minute<<":"<<sec<<endl;
}
int main()
{ Date date1(2009,11,14);//定义Date类对象date1
Time time1(6,12,18); //定义Time类对象time1
time1.showDate_Time(date1); return 0; }
3 友元类
1)友元类的说明方法是在另一个类声明中加入语句:
friend 类名;
例子:
#include<iostream>
using namespace std;
class Date; //对Date类的提前引用声明
class Time{ //声明类Time
public:
Time (int h,int m,int s) //定义构造函数
{ hour =h; minute =m; sec =s;}
void showDate_Time(Date&);
private:
int hour; int minute; int sec; };
class Date{ //声明类Date
public:
Date(int y,int m,int d) //定义构造函数
{ year=y; month=m; day=d; }
friend Time;
private:
int year; int month; int day;};
void Time::showDate_Time (Date& d) {cout<<d.year<<"."<<d.month<<"."<<d.day<<endl;
cout<<hour<<":"<<minute<<":"<<sec<<endl;
}
int main()
{ Date date1(2009,11,14);//定义Date类对象date1
Time time1(6,12,18); //定义Time类对象time1
time1.showDate_Time(date1); return 0; }
注(1)友元关系是单向的,不具有交换性和传递性
4 类的组合
1) 在一个类中内嵌另一个类的对象作为数据成员,称为类的组合。该内嵌对象称为对象成员,也称为子对象
问???? 类X中含有对象成员y后,如何完成对象成员a的初始化工作? 类X的构造函数如何定义?
例如有以下的类X :
class X {
类名1 对象成员名1;
类名2 对象成员名2;
…
类名n 对象成员名n;
};
类X的构造函数的定义形式为:
X∷X(参数表0):对象成员名1(参数表1),对象成员名2
(参数表2),…,对象成员名n(参数表n)
{
类B的构造函数体
}
参数表1、参数表2 、… 、参数表n的数据,一般来自参数表0
注
1)
调用构造函数D∷D( )时:
首先按各对象成员在类定义中的顺序依次调用它们的构造函数,对这些对象初始化。
最后再执行D∷D( )的函数体。
2)
撤销类D的对象d1时,调用析构函数的调用顺序与调用构造函数的顺序相反。
例如://例4.22 对象成员的初始化。
#include<iostream>
using namespace std;
class X{ //声明类X
public:
X(int a1,double b1){ a=a1; b=b1; }
void disp() { cout<<"a="<<a<<endl;cout<<"b="<<b<<endl; }
private:
int a; double b; };
class Y{ //声明类Y
public:
Y(int a1,double b1,int c1) :xx(a1,b1) { c=c1;} //定义类Y的构造函数,应缀上对象成员xx的初始化表
void disp() { xx.disp(); cout<<"c="<<c<<endl; }
private:
X xx; //声明类X的对象xx为类Y的对象成员
int c; };
int main()
{ Y b(123,456,789);
b.disp(); return 0; }
5 数据共享保护
1 常引用
1)如果在说明引用时用const修饰,则被说明的引用为常引用
int a=5;
const int& b=a
在实际应用中,常引用往往用来作函数的形参,这样的参数称为常参数
2 常对象
用const修饰说明的对象为常对象。常对象的数据成员值在对象的整个生存期内不能被改变
规定:
在定义对象时必须进行初始化,而且不能被更新
3 常对象成员
1). 常数据成员
使用const说明的数据成员称为常数据成员。
如果在一个类中说明了常数据成员,那么构造函数就只能通过初始化列表对该数据成员进行初始化,
而不能采用在函数中直接赋值的方法
#include<iostream> 例4.26-1 常数据成员举例。
using namespace std;
class Date {
private:
const int year;
const int month;//常数据成员
const int day;
public:
Date(int y,int m,int d);
void showDate(); };
Date::Date(int y,int m,int d) :year(y),month(m),day(d)
{ }
inline void Date::showDate()
{ cout<<year<<"."<<month<<"."<<day<<endl;}
int main()
{ Date date1(2009,10,15);
date1.showDate(); return 0; }
2.常成员函数
在类中用关键字const说明的函数为常成员函数,常成员函数的说明格式如下:
类型说明符 函数名(参数表)const;
const是函数类型的一个组成部分,因此 在函数的实现部分也要带关键字const。
在调用时不必加const。
如果将一个对象说明为常对象,则通过该对象只能调用它的常成员函数,而不能调用普通的成员函数。