nullC++语言编程C++语言编程 宁 博程序设计方法的发展历程程序设计方法的发展历程面向过程的程序设计方法
程序的目的:用于数学计算
主要工作:设计求解问题的过程
缺点:对于庞大、复杂的程序难以开发和维护
程序设计方法的发展历程程序设计方法的发展历程面向过程的结构化程序设计方法
设计思路
自顶向下、逐步求精。采用模块分解与功能抽象,自顶向下、分而治之
程序结构
按功能划分为若干个基本模块
各模块间的关系尽可能简单,功能上相对独立;每一模块内部均是由顺序、选择和循环三种基本结构组成
其模块化实现的具体方法是使用子程序程序设计方法的发展历程程序设计方法的发展历程面向过程的结构化程序设计方法
优点
有效地将一个较复杂的程序系统设计任务分解成许多易于控制和处理的子任务,便于开发和维护。程序设计方法的发展历程程序设计方法的发展历程面向过程的结构化程序设计方法
缺点:可重用性差、数据安全性差、难以开发图形界面的应用
把数据和处理数据的过程相互独立
当数据结构改变时,所有相关的处理过程都要进行相应的修改
图形用户界面的应用,很难用过程来描述和实现,开发和维护都很困难面向对象的设计思想面向对象的设计思想面向对象的程序设计方法
将数据及对数据的操作方法封装在一起,作为一个相互依存、不可分离的整体——对象。
对同类型对象抽象出其共性,形成类。
类通过一个简单的外部接口,与外界发生关系
基本设计思想
封装
软件复用面向对象的设计思想面向对象的设计思想面向对象的程序设计方法
优点
程序模块间的关系更为简单,程序模块的独立性、数据的安全性就有了良好的保障。
通过继承与多态性,可以大大提高程序的可重用性,使得软件的开发和维护都更为方便面向对象的基本概念 ---- 对象面向对象的基本概念 ---- 对象一般意义上的对象
是现实世界中一个实际存在的事物。
可以是有形的(比如一辆汽车),也可以是无形的(比如一项计划)。
是构成世界的一个独立单位,具有:
静态特征:可以用某种数据来描述
动态特征:对象所
表
关于同志近三年现实表现材料材料类招标技术评分表图表与交易pdf视力表打印pdf用图表说话 pdf
现的行为或具有的功能
面向对象的基本概念 ---- 对象面向对象的基本概念 ---- 对象面向对象方法中的对象
是系统用来描述客观事物的一个实体,它是用来构成系统的一个基本单位。对象由一组属性和一组行为构成。
属性:用来描述对象静态特征的数据项。
行为:用来描述对象动态特征的操作。面向对象的基本概念 ---- 类面向对象的基本概念 ---- 类分类——人类通常的思维方法
分类所依据的原则——抽象
忽略事物的非本质特征,只注意那些与当前目标有关的本质特征,从而找出事物的共性,把具有共同性质的事物划分为一类,得出一个抽象的概念。
例如,石头、树木、汽车、房屋等都是人们在长期的生产和生活实践中抽象出的概念。面向对象的基本概念 ---- 类面向对象的基本概念 ---- 类面向对象方法中的"类"
具有相同属性和行为的一组对象的集合
为属于该类的全部对象提供了抽象的描述,包括属性和行为两个主要部分。
类与对象的关系: 犹如模具与铸件之间的关系,一个属于某类的对象称为该类的一个实例。面向对象的基本概念 ---- 封装面向对象的基本概念 ---- 封装把对象的属性和行为结合成一个独立的系统单位
尽可能隐蔽对象的内部细节。对外形成一个边界(或者说一道屏障),只保留有限的对外接口使之与外部发生联系。面向对象的基本概念 ---- 继承面向对象的基本概念 ---- 继承继承对于软件复用有着重要意义,是面向对象技术能够提高软件开发效率的重要原因之一。
定义:特殊类的对象拥有其一般类的全部属性与行为,称作特殊类对一般类的继承。
例如:将Person作为一个一般类,Student便是一个特殊类。面向对象的基本概念 ---- 多态性面向对象的基本概念 ---- 多态性多态性是指在一般类中定义的属性或行为,被特殊类继承之后,可以具有不同的数据类型或表现出不同的行为。这使得同一个属性或行为在一般类及其各个特殊类中具有不同的语义。
例如:
数的加法->实数的加法 ->复数的加法C++语言概述C++语言概述C++语言的产生
C++的特点
一个简单的C++程序实例C++语言的产生C++语言的产生C++是从C语言发展演变而来的,首先是一个更好的C。
引入了类的机制,最初的C++被称为"带类的C"。
1983年正式取名为C++。C++语言的
标准
excel标准偏差excel标准偏差函数exl标准差函数国标检验抽样标准表免费下载红头文件格式标准下载
化工作从1989年开始,于1994年制定了ANSI C++标准草案。以后又经过不断完善,成为目前的C++。C++的特点C++的特点全面兼容C
它保持了C的简洁、高效和接近汇编语言等特点
对C的类型系统进行了扩充
C++也支持面向过程的程序设计,不是一个纯正的面向对象的语言
支持面向对象的方法
类、对象、继承、抽象、封装、….一个简单的C++程序实例一个简单的C++程序实例#include
void main(void)
{
cout<<"Hello!\n";
cout<<"Welcome to c++!\n";
}
一个简单的C++程序实例一个简单的C++程序实例运行结果:
Hello!
Welcome to c++!注释注释C中的注释:块注释 /* */
/* This is a comment */
不允许嵌套
C++中的注释
C++继承了C的块注释方式
增加了一种行注释方式
C++把任何一行中从“//”开始直到该行结束的所有内容皆视为注释注释 ---- 一个简单的例子注释 ---- 一个简单的例子#include
#include
void main()
{ // Checking if a keyword is ESC
int i, key;
while( 1 ) {
key = getch(); // Get a key from console
if (key == ‘\x1B’ {
printf(“\nEscape! ”);
return;
}
else printf(“\nKeycode is %2XH”, key);
}
}作用域作用域模块:在C语言中模块的概念是指在花括号{}之间的一组语句
作用域的种类
局部模块作用语:变量定义在模块范围内
文件作用域:变量定义在全局范围内,只限于当前文件的存取;
全局作用域:变量定义在全局范围内,对全程序有效。实现方式:include和extern
类作用域:变量定义在类中,在类范围内有效
作用域作用域: : 运算符: 指明作用域。
例 int x;
void f()
{ int x=1;
::x=2;
return;
}
作用域 ---- 一个简单的例子作用域 ---- 一个简单的例子#include
int global = 10;
void main() {
int global = 5;
printf(“The value of global is : %d\n”, global);
return;
}作用域 ---- 作用域分辨操作符作用域 ---- 作用域分辨操作符全局变量访问
::global
#include
int global = 10;
void main() {
int global = 5;
printf(“The value of inner global is : %d\n”, global);
printf(“The value of outer global is : %d\n”, ::global);
return;
}指针指针指针是C语言的一个非常重要的特征
实际上是内存地址,非常灵活且非常高效
但又潜伏着非常大的危险性
具有数据类型,可以进行指针运算
无值型指针,void *,是一种非常有用且十分灵活的指针类型
常量指针常量指针定义格式
const type * ptr_name;
其含义是指向常量的指针
不允许通过指针来修改其指向的对象的值
可以修改指针的值
例子
const int * ptr;
const int i=10;
ptr = & i; // 修改指针的值
*ptr = i+10; // 错误操作,试图修改指针指向的内容常量指针常量指针例子
const char * ptr;
const char str[10]=“hehehe”;
ptr = str; // 指针赋值
ptr[3] = ‘ ’; // 错误操作,试图修改指针指向的内容常量指针常量指针
const int * ptr;
int i=10;
ptr = &i; // 指针赋值, 等价于(const int *)&i
*ptr = 15; // 错误操作,试图修改指针指向的内容
i++;
cout << “i = ” << *ptr << endl;
输出结果为:11常量指针常量指针不允许将const类型的变量地址赋值给一般的变量指针
int * ptr;
const int i = 10;
ptr = &i; // 编译错误
ptr = (int *)&i; // 正确
*ptr = *ptr + 1;
cout << “i = ” << *ptr << endl;
输出结果为:11指针常量指针常量定义格式
type * const ptr_name;
其含义是指针变量的值不可改变
不允许修改指针变量的地址值
可以修改指针指向的变量值,如果指向的对象不是一个常量的话
例子
int * const ptr1;
void * const ptr2;指针常量指针常量int num=10;
int * const const_ptr = #
const int * ptr_to_const = #
int const * ptr = #
const_ptr =(int * const) & num; // 编译错误
//试图修改一个指针常量的地址值
*ptr = num; // 编译错误
//试图修改常量指针指向的对象值void类型void类型1.说明函数没有返回值;
void fun(void)
{ return ;}
2.表示函数不需要任何入口参数;
double fun(void)
{ }
3.可将指针说明为void型。这种指针可被赋以其它任何类型的指针。
double a=9.0;
double *pd=&a;
void *p;
p=pd;
练习练习 用指针写一个swap函数,交换两个整数 a和b的值。打印交换前后a,b的值。引用引用先看一个简单的例子
int i, &j=i;
i=1;
cout<<“i=” <
#include
void main(){
int n;
char *pc;
cout<<"请输入动态数组的元素个数"<>n;
pc=new char[n]; //
strcpy(pc,"堆内存的动态分配");
cout<
class Watch
{
......//类的定义略
}
//......类的实现略
void main(void)
{ Watch myWatch;
myWatch.SetTime(8,30,30);
myWatch.ShowTime();
}构造函数构造函数构造函数的作用是在对象被创建时使用特定的值构造对象,或者说将对象初始化为一个特定的状态。
在对象创建时由系统自动调用。
如果程序中未定义出,则系统自动产生出一个缺省形式的构造函数 ---- 缺省构造函数
允许为内联构造函数、重载构造函数、带缺省形参值的构造函数
构造函数构造函数定义说明
构造函数名与所在的类名相同;
构造函数没有返回类型,因此在定义构造函数时不能带有任何带有返回值的返回语句;
不能将构造函数说明为void类型;
可以有返回语句 return;
构造函数只能用于构造类的实例对象,它的调用是隐含的,不能对任何已经构造的对象再次进行构造函数的显式调用;
构造函数构造函数定义说明
构造函数一般总是被定义为公有成员,否则在外部定义类对象时无法对其进行初始化
构造函数的定义与普通成员函数一样,可以在类定义体内部,也可以放在类定义体的外部,且可以直接访问其类所在的所有其他成员,包括成员数据和成员函数构造函数构造函数定义说明
class Person {
int age;
Person() {
age=0;
};
};
class Student :public Person {
int stno;
};
Person p; // 编译错误必须将该构造函数变为公有成员构造函数构造函数一个类可以有多个构造函数,和普通函数一样,同名的构造函数相互重载
Class d_String {
Public:
d_String();
d_String(const d_String *);
d_String(const char *);
……
};构造函数构造函数对象的初始化
d_String str1; // 调用缺省构造函数
d_String str1(); // 调用缺省构造函数
d_String str1(“Bing Wang”); // 调用构造函数
d_String str1=d_String(); // 调用缺省构造函数
d_String str1=d_String(“Bing Wang”);
// 调用构造函数构造函数构造函数构造函数一般用来对对象的成员数据进行初始化
当类的成员数据比较多时这种初始化语句比较多
Class Account {
public:
Account() {
_name = 0;
_balance = 0.0;
_acct_nmbr = 0;
};构造函数构造函数 Account(const char * name, double balance, int acct_nmbr) {
_name = new char [ strlen(name)+1 ];
strcpy(_name, name);
_balance = balance;
_acct_nmbr = acct_nmbr;
};
……..
};构造函数构造函数成员初始化表
Class Account {
public:
Account() : _name ( 0), _balance (0.0),
_acct_nmbr (0) {};
Account(const char * name, double balance, int acct_nmbr) :
balance = balance, _acct_nmbr = acct_nmbr;
{ _name = new char [ strlen(name)+1 ];
strcpy(_name, name);
};
……..
};
初始化列表的效率比赋值语句的效率要高成员初始化表构造函数构造函数const成员函数
一个类中的成员函数可以是const
class d_Set {
public: d_Set();
unsigned long cardinality() const;
d_Boolean is_empty() const;
……
}const成员函数const成员函数const成员函数含义是该函数只能读取该类中的成员数据,而不能修改,因此
该成员函数不能修改所在类的成员数据
该成员函数不能调用所在类中的非const成员函数
根据const成员函数的定义
不能将构造函数定义为const类型,因为它要初始化成员数据的值
const关键字可以被用于参与对重载函数的区分
const是函数类型的一个组成部分,因此在实现部分也要带const关键字。const对象const对象const对象与其他类型的const对象一样
const对象调用构造函数初始化对象后不能再被修改
const d_String str1 = “Bing Wang”;
….
str1 = “Bing Wang”; //错误
通常,const对象只能调用const成员函数 举例举例#include
class R
{ public:
R(int r1, int r2){R1=r1;R2=r2;}
void print();
void print() const;
private:
int R1,R2;
};
举例举例void R::print()
{ cout<dim)
this->x[n] = val;
}
上述程序中this指针可缺省Void Write(int n, double val)
{ if (a < dim) x[n] = val;
}
隐含的this指针隐含的this指针This指针除了上述用法之外,可以使用在返回值中
class Screen {
Public: Screen();
Screen & set( char );
Screen & move( int, int );
Screen & clear();
Screen & display();
Private: …….// 数据成员说明
}; 隐含的this指针隐含的this指针This指针除了上述用法之外,可以使用在返回值中
Screen & Screen::clear( char bg) {
_cursor = 0;
_screen.assign(_screen.size(), bg);
return *this;
}
myScreen.clear().move(2,2).set(‘*’).display();缺省构造函数缺省构造函数缺省构造函数是指没有参数的构造函数
当类的定义中没有定义构造函数时,系统会为该类生成一个缺省构造函数,在进行对象说明时系统会调用系统生成的缺省构造函数
系统生成的缺省构造函数不做任何事情
当类中用户定义了构造函数后,编译器就会忽略系统生成的缺省构造函数,即使你没有定义缺省构造函数
建议用户定义自己的缺省构造函数,因为系统生成的缺省构造函数不做任何事情缺省构造函数缺省构造函数Class d_String {
Public:
d_String(); // 缺省构造函数
d_String(const d_String *);
d_String(const char *);
……
};
d_String str; // 调用用户定义的缺省构造函数缺省构造函数缺省构造函数Class d_String {
Public:
//d_String(); // 缺省构造函数
//d_String(const d_String *);
//d_String(const char *);
…… // 没有其它构造函数定义
};
d_String str; // 调用系统生成的缺省构造函数缺省构造函数缺省构造函数
Class d_String {
Public:
//d_String(); // 缺省构造函数
d_String(const d_String *);
d_String(const char *);
……
};
d_String str; // 编译错误,因为编译器忽略系
// 统生成的缺省构造函数拷贝构造函数拷贝构造函数拷贝构造函数是一种特殊的构造函数,其形参为本类的对象引用
class 类名
{ public :
类名(形参);//构造函数
类名(类名 &对象名);//拷贝构造函数
...
};
类名:: 类名(类名 &对象名)//拷贝构造函数的实现
{ 函数体 }拷贝构造函数拷贝构造函数class Location
{
public:
Location(int xx=0,int yy=0){X=xx; Y=yy;}
Location(Location & p);
int GetX() {return X;}
int GetY() {return Y;}
private:
int X,Y;
};拷贝构造函数拷贝构造函数如果没有定义类的拷贝构造函数,系统就会自动生成一个默认的拷贝构造函数,其功能是把初始值对象的每个数据成员的值都复制到新建立的对象中
何时调用拷贝构造函数
Location L1;
Location L2(L1); // 调用拷贝构造函数
Location L3 = L1; // 调用拷贝构造函数
F( L1 ); // 调用拷贝构造函数
L1 = g(); //调用拷贝构造函数, 为被返回
// 的对象建立一个临时对象拷贝构造函数拷贝构造函数课堂提问
既然系统能够自动生成一个默认的拷贝构造函数,那么用户是否还有必要生成自己的拷贝构造函数呢?理由是什么?浅拷贝与深拷贝浅拷贝与深拷贝浅拷贝 ---- 通过一个例子来理解浅拷贝的概念C语言的例子
char * p1, *p2;
p1 = malloc( 20 );
strcpy(p1, “Bin Wang”);
p2 = p1;Bin Wang指针p1指针p2浅拷贝与深拷贝浅拷贝与深拷贝浅拷贝 ---- 通过一个例子来理解浅拷贝的概念C++的例子
Class String {
String();
String(const char *)
~String();
private:
char * str;
};String::String() { str = 0; }
~String::String() { if (str!=0) delete str; }
String::String(const char * s) {
str = new char [strlen(s)+1];
strcpy(str, s);
}
String * s1 = new String(“Bin Wang”); //
String * s2 = new String (s1);
// 调用缺省拷贝构造函数浅拷贝与深拷贝浅拷贝与深拷贝浅拷贝 ---- 通过一个例子来理解浅拷贝的概念
浅拷贝的缺点
当一个指针指向同一个对象或内存单元时存在潜在的错误源泉,例如
当对象s1被析构以后,对象s2无法析构是由于缺省拷贝构造函数引起的,必须重写strstrBin Wangs1s2浅拷贝与深拷贝浅拷贝与深拷贝深拷贝
Class String {
String();
String(const char *);
String(String &);
~String();
private:
char * str;
};String::String() { str = 0; }
~String::String() { if (str!=0) delete str; }
String::String(const char * s) {
str = new char [strlen(s)+1];
strcpy(str, s);
}
String::String(String & s) {
str = new char [strlen(s.str)+1];
strcpy(str, s.str);
}
String * s1 = new String( “Bin Wang”);
String * s2 = new String( s1 ); 浅拷贝与深拷贝浅拷贝与深拷贝深拷贝
深拷贝可以很好地避免指针悬挂问题strstrBin Wangs1s2Bin Wang析构函数析构函数完成对象被删除前的一些清理工作。
在对象的生存期结束的时刻系统自动调用它,然后再释放此对象所属的空间。
如果程序中未定义析构函数,编译器将自动产生一个缺省的析构函数。
与构造函数一样,析构函数一般总是被说明为类的一个公有函数成员,由~加上函数名称构成,没有返回值,且没有任何参数析构函数析构函数当一个对象中没有涉及动态内存分配时,可以使用系统生成的缺省析构函数。如果涉及到动态内存问题时,应该编写自己的显式析构函数;否则存在内存泄漏问题
当然也可能存在需要处理的情况:在对象的生命周期内动态获得的各种资源,在析构函数中应该需要处理;例如该对象获得的互斥锁,在析构函数中应该释放该锁;析构函数析构函数Class Account {
Public: Account();
Account ( const char *, double = 0.0 );
Account ( const Account & );
~Account();
Private: char *_name;
unsigned int _acct_nmbr;
double _balance;
};inline
Account::~account()
{
delete [] _name;
}例1例1(1) Account global( “James Joyce” );
(2) int main() {
(3) Account local ( Anna Livia Plurabelle”, 10000 );
(4) Account & loc_ref = global;
(5) Account * pact = 0;
(6) { Account local_two ( “stephen hero” );
(7) pact = new Account( “Stephen Dedalus” );
(8) }
(9) delete pact;
(10) }例1例1该例子中调用了4次构造函数;
对应地,程序也要调用4次析构函数;类的应用举例类的应用举例一圆型游泳池如图所示,现在需在其周围建一圆型过道,并在其四周围上栅栏。栅栏价格为35元/米,过道造价为20元/平方米。过道宽度为3米,游泳池半径由键盘输入。要求编程计算并输出过道和栅栏的造价。
类的应用举例类的应用举例#inc