参考课本:《C++面向对象程序设计》刘磊 电子科技大学出版社
面向对象程序设计是一种以对象为中心的思维方式面向将系统看成通过交互作用来完成特定功能的对象的集合。每个对象用自己的方法来管理数据。也就是说只有对象内部的代码能够操作对象内部的数据。
不同:面向对象有三个主要特征:封装、继承、多态
结构化程序设计由三个基本结构构成:顺序结构、选择结构、循环结构
1)对象:对象是人们要进行研究的任何事物,它不仅能表示具体的事物,还能表示抽象的规则、计划或事件。对象具有状态,一个对象用数据值来描述它的状态。对象还有操作,用于改变对象的状态,对象及其操作就是对象的行为。对象实现了数据和操作的结合,使数据和操作封装于对象的统一体中。
2)类:具有相同特性(数据元素)和行为(功能)的对象的抽象就是类。因此,对象的抽象是类,类的具体化就是对象,也可以说类的实例是对象,类实际上就是一种数据类型。类具有属性,它是对象的状态的抽象,用数据结构来描述类的属性。类具有操作,它是对象的行为的抽象,用操作名和实现该操作的方法来描述。
类与对象的关系就如模具和铸件的关系,类的实力化的结果就是对象,而对对象的抽象就是类,类描述了一组有相同特性(属性)和相同行为的对象。
任何事物都是对象。可以是一个有形的、具体存在的事物。也可以是无形的、抽象的事件
面向对象程序设计技术必须提供一个机制允许一个对象与另一个对象的交互,这种机制称为消息传递机制。
消息的性质:
(1)同一个对象可以接受不同形式的多个消息,做出不同的响应
(2)相同形式的消息可以传递给不同的对象,所做出的响应可以是不同的
(3)对消息的响应并不是必须的
对象所能实现的行为在面向对象程序设计方法中称为方法
抽象是将有关事物的共性归纳、集中的过程。抽象是对复杂世界的简单表示,抽象并不打算了解全部的问题,而只强调感兴趣的信息,忽略了与主题无关的信息。例如:在设计一个成绩管理程序的过程中,只关心学生的姓名、学号、成绩等,而对他的身高体重等信息就可以忽略。而在学生健康信息管理系统中,身高、体重等信息必须抽象出来,而成绩则可以忽略。
抽象是通过特定的实例抽取共同性质后形成概念的过程。面向对象程序设计中的抽象包括两个方面:数据抽象和代码抽象(或称为行为抽象)。前者描述某类对象的属性或状态,也就是此类对象区别于彼类对象的特征物理量;后者描述了某类对象的公共行为特征或具有的公共功能。
在现实世界中,所谓封装就是把某个事物包围起来,使外界不知道该事物的具体内容。在面向对象程序设计中,封装是指把数据和实现操作的代码集中起来放在对象内部,并尽可能隐蔽对象的内部细节。
下面以一台洗衣机为例,说明对象的封装特征。首先,每一台洗衣机有一些区别于其他洗衣机的静态属性。如出厂日期、机器编号等。另外,洗衣机上有一些按键,如“启动”、“暂停”、“选择”等,当人们使用洗衣机时,只需要根据需要按下“选择”、“启动”或“暂停”等按键,洗衣机就会完成相应的工作。这些按键安装在洗衣机的表面,人们通过他们与洗衣机交流,告诉它应该做什么。我们无法(也没必要)操作洗衣机的内部电路和机械控制部件,因为它们被装在洗衣机里面,这对于用户来说是隐蔽的,不可见的。
继承所表达的是类之间的相关关系,这种关系使得某类对象可以继承另外一类对象的特征和能力。现实生活中,继承是很普遍和容易理解的。例如:我们继承了父母的一些特征,如种族、血型、眼睛的颜色等,父母是我们所具有的属性的基础。
以面向对象程序设计的观点,继承所表达的是类之间相关的关系。这种关系使得某一类可以继承另一类的特征和能力。
(1)传统程序设计开发软件的生产效率低下
(2)传统程序设计难以应付日益庞大的信息量和多样的信息类型
(3)传统程序设计难以适应各种新环境
(1)可提高程序的重用性
(2)可控制程序的复杂性
(3)可改善程序的复杂性
(4)可改善程序的可维护性
(5)能够更好地支持大型程序设计
(6)增强了计算机处理信息的范围
(7)能很好的适应新的硬件环境
1.C++在C语言基础上引入了面对对象的机制,同时也兼容C语言。
2.C++有三大特性:①封装;②继承;③多态;
3.C++语言编写出的程序结构清晰、易于扩充,程序可读性好。
4.C++生成的代码质量高,运行效率高,仅比汇编语言慢10%~20%;
5.C++更加安全,增加了const常量、引用、四类cast转换(static_cast、dynamic_cast、const_cast、reinterpret_cast)、智能指针以及try—catch等等;
6.C++可复用性高,C++引入了模板的概念,后面在此基础上,实现了方便开发的标准模板库STL(Standard Template Library)。
命名空间
在C/C++中,变量、函数和后面要学到的类都是大量存在的,这些变量、函数和类的名称将都存在于全局作用域中,可能会导致很多冲突。使用命名空间的目的是对标识符的名称进行本地化,以避免命名冲突或名字污染,namespace关键字的出现就是针对这种问题的。
命名空间的使用有三种方式:
1.加命名空间名称及作用域限定符
2.使用using将命名空间中成员引入
3.使用using namespace 命名空间名称引入
1、内联函数中不可含有循环;
2、内联函数中不可含有switch语句;
3、内联函数中不可能含有静态变量;
4、内联函数不可为递归函数;
5、内联函数中不可含有错误处理。
重载函数通常用来命名一组功能相似的函数,这样做减少了函数名的数量,避免了名字空间的污染,对于程序的可读性有很大的好处。
函数模板:函数的重载能够实现一个函数名多用,将实现相同或者相似功能的函数用同一个函数名来定义,但是在程序中仍然要分别定义每一个函数。为进一步简化,C++提供了函数模板,实际上是建立一个通用函数,其函数类型和形参类型不具体指定,用一个虚拟的类型来代表,此通用函数即为函数模板。在调用函数时系统会根据实参的类型来取代模板中的虚拟类型,从而实现不同函数的功能。
模板函数:为函数模板传参,根据实际传入的参数类型生成的一个重载函数即为模板函数,它是函数模板的一次实例化。
1.
#include
using namespace std;
void main()
{
int* p = new int[3];
for (int i = 0; i < 3; i++)
p[i] = i;
for (int i = 0; i < 3; i++)
cout << p[i] << " ";
cout << endl;
p[1]++;
cout << "p[0]=" << p[0] << ",p[1]=" << p[1] << "\n";
delete [ ]p;
}
结果:
0 1 2
p[0]=0,p[1]=2
2.
#include
using namespace std;
void main()
{
int i = 5, & n = i, & k = n;
i = ++n - 2;
cout << "i=" << i << endl;
}
i=4
1.使用c++语言中的预定义的流类对象cin和cout,编程实现从键盘输入年和月,计算并输出该年的月份共有多少天。
#include
using namespace std;
int main()
{
int year, month, day, cnt;
cin >> year >> month;
if ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0)
cnt = 1;
else cnt = 0;
switch (month)
{
case 1:
case 3:
case 5:
case 7:
case 8:
case 10:
case 12: day = 31; break;
case 4:
case 6:
case 9:
case 11: day = 30; break;
case 2: day = 28 + cnt; break;
}
cout << "该年该月有" << day << "天";
return 0;
}
2.用函数重载分别实现整型、长整型、双精度型数据的三次方的计算。
#include
using namespace std;
int zhengxing(int n)
{
return n * n * n;
}
long changzhengxing(long long n)
{
return n * n * n;
}
double shuangjingdu(double n)
{
return n * n * n;
}
int main()
{
int i; long long j; double k;
cin >> i >> j >> k;
cout << zhengxing(i) << " " << changzhengxing(j) << " " << shuangjingdu(k) << endl;
return 0;
}
构造函数的作用:初始化对象的成员变量
析构函数的作用:析构函数往往用来做“清理善后” 的工作(例如在建立对象时用new开辟了一片内存空间,delete会自动调用析构函数后释放内存)
1、public:public表明该数据成员、成员函数是对所有用户开放的,所有用户都可以直接进行调用
2、private:private表示私有,私有的意思就是除了class自己之外,任何人都不可以直接使用。
3、protected:protected对于子女、朋友来说,就是public的,可以自由使用,没有任何限制,而对于其他的外部class,protected就变成private。互为友好关系的类。
拷贝构造函数就是复制构造函数
调用时间:
(1)当用类的一个对象去初始化该类的另一个对象时,系统会自动调用拷贝构造函数;
(2)将一个对象作为实参传递给一个非引用类型的形参,系统会自动调用拷贝构造函数;
(3)从一个返回类为非引用的函数返回一个对象时,系统会自动调用拷贝构造函数;
(4)用花括号列表初始化一个数组的元素时,系统会自动调用拷贝构造函数。
数据成员,盛装两个运算量,还有字符成员,盛装运算符
#include
using namespace std;
class time
{
private:
int H;
int M;
int S;
public:
bool setTime(int ,int ,int );
void print();
bool isValid(int ,int ,int );
};
bool time:: setTime(int h,int m,int s)
{
if(isValid(h,m,s))
{
H=h,M=m,S=s;
return true;
}
else
return false;
}
void time:: print()
{
cout<24||h<1||m>60||m<1||s>60||s<1) return false;
else
return true;
}
int main()
{
time t;
int h,m,s;
cin>>h>>m>>s;
while(!t.setTime(h,m,s))
{
cout<<"data error please input again:";
cin>>h>>m>>s;
}
t.print();
return 0;
}
#include
#include
using namespace std;
class CStudent
{
private:
int id;
string name;
int math;
int english;
static int count;
static int mathc;
static int englishc;
public:
void setms()
{
cout << "name id math english" << endl;
cin >> name >> id >> math >> english;
count++;
mathc = mathc + math;
englishc = englishc + english;
}
int add()
{
return math + english;
}
void outms()
{
cout << "id"< S[i + 1].add())
{
*p = S[i];
S[i] = S[i + 1];
S[i + 1] = *p;
}
}
}
for (i = 9; i > 7; i--)
{
S[i].outms();
}
delete p;
return 0;
}
//顺序栈
#include
#include
using namespace std;
#define Maxsize 100
typedef int DataType;
struct SeqStack{
//int MAXNUM;
int t;
DataType *s;
};
typedef struct SeqStack *PSeqStack;
PSeqStack createEmptyStack_seq(int m)
{
PSeqStack pastack = (PSeqStack)malloc(sizeof(struct SeqStack));
if(pastack!=NULL)
{
pastack->s = (DataType *)malloc(sizeof(DataType)*m);
if(pastack->t ){
//pastack->MAXNUM = m;
pastack->t = -1;
return pastack;
}
else free(pastack);
}
printf("Out of space!!\n");
return NULL;
}
int isEmptyStack_seq(PSeqStack pastack){
return(pastack->t == -1);
}
void push_seq(PSeqStack pastack,DataType x)
{
if(pastack->t>=Maxsize -1)
printf("Overflow!\n");
else
{
pastack->t = pastack->t+1;
pastack->s[pastack->t ] = x;
}
}
void pop_seq(PSeqStack pastack)
{
if(pastack->t == -1)
{
printf("Underflow!\n");
}
else
pastack->t = pastack->t-1;
}
DataType top_seq(PSeqStack pastack)
{
if(pastack->t == -1)
{
printf("It is empty!\n");
}
else
return (pastack->s[pastack->t]);
}
int main()
{
PSeqStack pastack = createEmptyStack_seq(5);
int flage = isEmptyStack_seq(pastack);
push_seq(pastack,1);
push_seq(pastack,3);
push_seq(pastack,5);
push_seq(pastack,9);
pop_seq(pastack);
printf("%d",top_seq(pastack));
return 0;
}
//链栈
#include
#include
struct Node;
typedef struct Node *PNode;
typedef int DataType;
struct Node{
DataType info;
PNode link;
};
struct LinkStack{
PNode top;
};
typedef struct LinkStack *PLinkStack;
PLinkStack createEmptyStack_link(void)
{
PLinkStack plstack;
plstack = (PLinkStack)malloc(sizeof(struct LinkStack));
if(plstack!=NULL)
plstack->top = NULL;
else
printf("Out of space!\n");
return plstack;
}
int isEmptyStack_link(PLinkStack plstack)
{
return (plstack->top ==NULL);
}
void push_link(PLinkStack plstack,DataType x)
{
PNode p;
p = (PNode)malloc(sizeof(struct Node));
if(p==NULL)
{
printf("Out of space!\n");
}
else
{
p->info = x;
p->link = plstack->top ;
plstack->top = p;
}
}
void pop_link(PLinkStack plstack)
{
PNode p;
if(isEmptyStack_link(plstack))
printf("Empty stack pop.\n");
else
{
p = plstack->top;
plstack->top = plstack->top->link ;
free(p);
}
}
DataType top_link(PLinkStack plstack)
{
if(plstack->top == NULL)
{
printf("Stack is empty!\n");
}
else
return (plstack->top ->info);
}
int main()
{
PLinkStack plstack = createEmptyStack_link();
int flag = isEmptyStack_link(plstack);
push_link(plstack,3);
push_link(plstack,5);
push_link(plstack,6);
push_link(plstack,10);
pop_link(plstack);
printf("%d",top_link(plstack));
return 0;
}
_dh
#include
using namespace std;
class date
{
public:
date(int, int, int);
date(int, int);
date(int);
date();
void display();
private:
int month;
int day;
int year;
};
date::date(int m, int d, int y) :month(m), day(d),year(y){}
date::date(int m, int d) :month(m), day(d) { year = 2005; }
date::date(int m) : month(m) { day = 1; year = 2005; }
date::date() { month = 1; day = 1; year = 2005; }
date::date() { month = 1; day = 1; year = 2005; }
void date::display()
{
cout << month << " " << day << "/" << year << endl;
}
int main()
{
date d1(10, 13, 2005);
date d2(12, 30);
date d3(10);
date d4;
d1.display();
d2.display();
d3.display();
d4.display();
return 0;
}
结果同14
#include
using namespace std;
int main()
{
cout<<"this "<<"is ";
cout<<"a "<<"c++ ";
cout<<"program. "<
输出:this is a c++ program.
#include
using namespace std;
int main()
{
int a,b,c;
a=10;
b=23;
c=a+b;
cout<<"a+b=";
cout<
输出结果为:a+b=33
#include
using namespace std;
int main()
{
int a,b;
c=a+b;
cout>>"a+b=">>a+b;
}
有错误,c未声明且cout后面的符号方向反了。
#include
using namespace std;
int main()
{
int a,b,c;
int add(int,int);
cin>>a>>b;
c=add(a,b);
cout<<"a+b="<
#include
using namespace std;
int main()
{
int a,b,c,temp;
cin>>a>>b>>c;
if(a>b)
{
temp=a;
a=b;
b=temp;
}
if(a>c)
{
temp=a;
a=c;
c=temp;
}
if(b>c)
{
temp=b;
b=c;
c=temp;
}
cout<
_dh
#include
using namespace std;
class date
{
public:
date(int, int, int);
date(int, int);
date(int);
date();
void display();
private:
int month;
int day;
int year;
};
date::date(int m, int d, int y) :month(m), day(d),year(y){}
date::date(int m, int d) :month(m), day(d) { year = 2005; }
date::date(int m) : month(m) { day = 1; year = 2005; }
date::date() { month = 1; day = 1; year = 2005; }
date::date() { month = 1; day = 1; year = 2005; }
void date::display()
{
cout << month << " " << day << "/" << year << endl;
}
int main()
{
date d1(10, 13, 2005);
date d2(12, 30);
date d3(10);
date d4;
d1.display();
d2.display();
d3.display();
d4.display();
return 0;
}
#include
using namespace std;
class Student
{
public:
Student(int num,double score)
{
this -> num = num;
this ->score = score;
}
Student()
{
num = 0;
score = 0;
}
void display();
private:
int num;
double score;
};
void Student:: display()
{
cout << num << " : " << score << endl;
}
int main()
{
Student stu[5] = {Student(1001,80),Student(1002,85)
,Student(1003,90),Student(1004,95),Student(1005,100)};
Student *p = stu;
for(p = stu; p < stu + 5; p += 2)
{
p -> display();
}
return 0;
}
#include
using namespace std;
class student
{
public:
student(int n,float s):num(n),score(s){
}
void change(int n,float s)
{
num=s;
score=s;
}
void display()
{
cout<
#include
using namespace std;
class Date;
class Time
{
public:
Time(int, int, int);
void display(Date&);
private:
int hour;
int minute;
int sec;
};
class Date
{
public:
friend Time;
Date(int, int, int);
private:
int month;
int day;
int year;
};
Time::Time(int hour, int minute, int sec)
{
this->hour = hour;
this->minute = minute;
this->sec = sec;
}
void Time::display(Date& d)
{
cout << d.month << "/" << d.day << "/" << d.year << endl;
cout << hour << ":" << minute << ":" << sec << endl;
}
Date::Date(int month, int day, int year)
{
this->month = month;
this->day = day;
this->year = year;
}
int main()
{
Time t1(10, 13, 56);
Date d1(12, 25, 2004);
t1.display(d1);
return 0;
}