Presentation is loading. Please wait.

Presentation is loading. Please wait.

An Introduction to Object-Oriented Programming Using C++

Similar presentations


Presentation on theme: "An Introduction to Object-Oriented Programming Using C++"— Presentation transcript:

1 An Introduction to Object-Oriented Programming Using C++

2 《C++面向对象程序设计》教学内容 第1章 C++概述 第2章 类和对象 第3章 面向对象程序设计概述 第4章 进一步学习类和对象
第2章 类和对象 第3章 面向对象程序设计概述 第4章 进一步学习类和对象 第5章 堆与复制构造函数 第6章 继承性:派生类 第7章 运算符重载 第8章 虚函数和多态性 第9章 模板 第10章 类库和C++的标准模板库STL 第11章 输入输出流 第12章 异常处理

3 第一章 第1章 C++概述 C++ A Better C

4 1.1 C++起源和特点 C++的起源 C++的特点

5 1.2 C++程序的结构 1.2.1  C程序与C++程序比较 1.2.2  C++程序结构 1.2.3  C++程序的编辑、编译和运行

6 C程序与C++程序比较之一 main( ) main( ) { int a, b, sum; { int a, b, sum;
//定义三个整型变量 a = 123; b = 456; sum = a + b; cout<< sum; } main( ) { int a, b, sum; /* 定义三个整型变量 */ a = 123; b = 456; sum = a + b; printf("sum is %d\n", sum); }

7 C程序与C++程序比较之二 #include "stdio.h" #include “iostream.h" main( )
{ char a,b,c; a = 'B'; b = 'O'; c = 'Y'; putchar(a); putchar(b); putchar(c); } #include “iostream.h" void main( ) { char a,b,c; a = 'B'; b = 'O'; c = 'Y'; cout<<a<<b<<c; }

8 1.3 C++的一些新特性 1.3.1 单行注释和新的I/O流 1.3.2 const修饰符 1.3.3 内联函数 1.3.4 函数原型
1.3.3  内联函数 1.3.4  函数原型 1.3.5  带缺省参数的函数 1.3.6  函数名重载 1.3.7  new和delete运算符 1.3.8  引用(reference)

9 1.3.1 单行注释和新的I/O流 // I/O stream #include <iostream.h> main( )
{ int i; float f; char s[80];  cout <<"Enter an integer,float,and string:"; cin >>i>>f>>s; cout <<"Here's your data:"<<i<<' '<<f<<endl<<s<<'\n'; return 0; }

10 单行注释和新的I/O流(续) cout 是预定义的输出流对象,类似于C语言中的stdout。
cin 是预定义的输入流对象,类似于C语言中的stdin。 << 输入运算符,可用于输入C++语言中任何基本类型的数据。 (注意:输入和输出并不是C++语言的组成部分,它们由流库iostream支持。)

11 输入含有空格的字符串 // Use getline() to read a string that contains spaces.
#include <iostream> #include <fstream> using namespace std; int main() { char str[80]; cout << "Enter your name: "; cin.getline(str, 79); cout << str << '\n'; return 0; }

12 1.3.2 const 存取修饰符 对象 A:亲爱的,你千万不能变心? 对象 B:放心吧!亲爱的。 对象 A:你发誓!
对象 B:不用发誓,因为我是const ! const 对象 B;

13 常量 Constants 在C中,可以使用#define来定义符号常量 。
C++提供了一种更灵活、更安全的方式来定义常量,即使用关键字const来定义符号常量。 The concept of constant (expressed by the const keyword) was created to allow the programmer to draw a line between what changes and what doesn’t. This provides safety and control in a C++ programming project.

14 常量例子 Constant examples
const float PI = ; // PI是一个常量 const int v[ ]={1,2,3,4}; //数组元素v[i]是常量 const int x; // error: no initializer //定义常量时应初始化,否则出错。 void f( ) { model =200; // error v[2]++; // error } The keyword const can be added to the declaration of an object to make the object declared a constant. For example: const int model = 90; // model is a const const int v[ ]={1,2,3,4}; // v[i] is a const const int x; // error: no initializer Declaring something const ensures that its value will not change with its scope: Void f( ) { model =200; // error v[2]++; // error }

15 值替换 value substitution
#define BUFSIZE 100 const int bufsize = 100; Because of subtle bugs that the preprocessor might introduce, you should always use const instead of #define value substitution. When programming in C, we used to create macros and to substitute values. Because the preprocessor simply does text replacement and has no concept nor facility for type checking, preprocessor value substitution introduces subtle problems that can be avoided in C++ by using const values. The typical use of the preprocessor to substitute values for names in C looks like this: #define BUFSIZE 100 Now in C++ you can say const int bufsize = 100;

16 常量const和指针 The const modifies the thing it is “closest to.”
指针所指向的对象为常量 Pointer to const 指针本身为常量 const pointer The const modifies the thing it is “closest to.” When using const with pointers, you have two options: const can be applied to what the pointer is pointing to, or the const can be applied to the address stored in the pointer itself.

17 指向常量的指针 Pointer to const
const int* u; // pointer to constant *u=18; // error: u points to constant u= p; // OK So if you want to prevent any changes to the element you are pointing to, you write a definition like this: const int* u; Starting from the identifier, we read “u is a pointer, which points to a const int.” Here, no initialization is required because you’re saying that u can point to anything (that is, it is not const), but the thing it points to cannot be changed.

18 常指针 const pointer int d = 1; int* const w = &d; *w=2; // OK
w=p; // error: w is const const pointer To make the pointer itself a const, you must place the const specifier to the right of the *, like this: int d = 1; int* const w = &d; Now it reads: “w is a pointer, which is const, that points to an int.” Because the pointer itself is now the const, the compiler requires that it be given an initial value that will be unchanged for the life of that pointer. It’s OK, however, to change what that value points to by saying *w = 2;

19 const修饰函数参数 void print_salary (const float *salary) {
cout<<salary<<’\n’; } const可以阻止参数被函数修改

20 const 的其他用途 Other uses of const
return types, class objects and member functions The first motivation for const seems to have been to eliminate the use of preprocessor #defines for value substitution. It has since been put to use for pointers, function arguments, return types, class objects and member functions. All of these have slightly different but conceptually compatible meanings and will be discussed later.

21 volatile 存取修饰符 修饰符volatile通知编译器,变量值可能由程序中没有显示说明的方式所改变,因此在作编译优化时,不要通过将该变量放入寄存器来提高速度。 Volatile原意是:可变的,不稳定的 extern volatile clock; extern const volatile clock;

22 1.3.3 内联函数(内嵌函数, 内置函数 inline function)
inline int max(int x, int y) // max被说明为内联函数 { int z; if(x>y) z=x; else z=y; return (z); } 内联函数的调用方法与普通函数没有区别。

23 类中定义的内联函数Inline function
Any function defined within a class body is automatically inline, class Date{ int day, month, year; public: void init_date(int dd,int mm,int yy) {day=dd; month=mm; year=yy;} }; Here init_date is a inline function Any function defined within a class body is automatically inline, For example: but you can also make a non-class function inline by preceding it with the inline keyword. Here is an example of inline function which is not a member function of a class: inline int plusOne(int x) { return ++x; }

24 函数调用时的时间开销 1.函数调用时的时间开销:保护现场,恢复现场。
2.用关键字inline说明内嵌函数。编译器直接用内嵌函数体的编译代码插入在函数调用语句处,这一过程称为函数的嵌入扩展。利用内嵌函数减少了调用普通函数时的压栈和弹栈操作,从而提高程序的运行速度。 3.内嵌函数比带参数的宏的好处。 一般情况下,只有较短的函数才定义为内嵌函数。使用内嵌函数实际上是一种增加空间开销以减小时间开销的方法。

25 为什么使用内联函数 Efficiency 效率
在C程序中,可使用宏macros达到同样的目的,但是宏是通过预处理来处理的,不进行类型检查,容易造成难以发现的错误。 宏macros在类的内部不能使用,宏不能作为类的成员。 Why Using Inline Functions? Efficiency In C, one of the ways to preserve efficiency is through the use of macros, which allow you to make what looks like a function call without the normal function call overhead. The macro is implemented with the preprocessor instead of the compiler proper. Preprocessor macros eliminate function call overhead: pushing arguments, making an assembly-language CALL, returning arguments, and performing an assembly-language RETURN.

26 为什么使用内联函数(cont.) 为了克服宏的上述缺陷, C++ 引入了内联函数。内联函数具有高效率,而且:
进行类型检查,避免出现类型不匹配的错误。 可以作为类的成员函数。 To retain the efficiency of the preprocessor macro, but to add the safety and class scoping of true functions, C++ has the inline function. There are two problems with the use of preprocessor macros in C++. The first is also true with C: a macro looks like a function call, but doesn’t always act like one. This can bury difficult-to-find bugs. The second problem is specific to C++: the preprocessor has no permission to access class member data. This means preprocessor macros cannot be used as class member functions. To retain the efficiency of the preprocessor macro, but to add the safety and class scoping of true functions, C++ has the inline function.

27 How do inline functions work 编译器处理内联函数的过程
类型检查 Type checking (To assure safety ) 将函数代码插入到函数调用处 then substitutes the function body for the function call 这样函数代码将占据更所得存储空间 The inline code does occupy space The short,small and frequently called functions are suitable for inline functions. When you use inline function, the compiler checks to ensure the call is correct and the return value is being used correctly, and then substitutes the function body for the function call, thus eliminating the overhead. (The inline function reduce the time of a function call and thus preserve the efficiency.) The inline code does occupy space, but if the function is small, this can actually take less space than the code generated to do an ordinary function call (pushing arguments on the stack and doing the CALL).

28 1.3.4 函数原型 ( function prototype )
什么是函数原型? 描述函数原型的三大要素: 函数名 参数类型 函数返回值类型 函数原型的例子: int translate(float x, float y, float z); int translate(float, float, float);

29 【例1.7】 void sqr_it( ); /* function declaration */ int main( ) { int x;
sqr_it(x); printf("The square of x is %d\n",x); return 0; } void sqr_it(int *i) { *i=(*i)*(*i);

30 运行时出错 【例1.7】本例的C程序能够成功通过诸如Turbo C这样的C编译器的检查,但会在运行阶段发生错误。
该程序运行后的结构显示如下: The square of x is 10 Null pointer assignment

31 使用函数原型执行强类型检查【例1.8】 void sqr_it(int *i); //函数原型 int main( ) { int x;
sqr_it(x); cout<<"The square of x is "<<x<<'\n'; return 0; } void sqr_it(int *i) { *i=(*i)*(*i); type mismatch 类型不匹配

32 函数原型的作用 C++语言是强类型化语言,任何函数在使用以前必须有该函数的原型说明,以便进行实际参数与形式参数之间的类型匹配检查。
函数返回值的类型和函数参数的类型、个数、次序在函数声明,函数定义和函数调用时必须匹配。 C++语言的编译器执行上述检查能显著减少很多隐藏的错误。

33 函数原型与C语言的函数类型说明 函数原型是在C语言的函数类型说明(函数声明)的基础上进行扩充后形成的,
它不但说明了函数返回值的类型,还要确定函数参数的类型、个数、次序及缺省值。

34 1.3.5 带缺省参数的函数 例如:以下函数带有一个缺省值为0的参数。 void myfunc(double d=0.0) { … }
1.3.5  带缺省参数的函数 例如:以下函数带有一个缺省值为0的参数。 void myfunc(double d=0.0) { … } myfunc( ); // pass an explicit value myfunc( ); // let function use default

35 缺省参数的例子 带缺省参数函数主要由两个作用:简化编程;有利于程序扩充,而不影响原有代码。
void DrawCircle(int x,int y,int r=10); DrawCircle(50,20); DrawCircle(50,100,30); 带缺省参数函数主要由两个作用:简化编程;有利于程序扩充,而不影响原有代码。

36 1.3.6 函数名重载(overload ) 两或两个以上的函数共享同一个名称,就称为函数名重载。 Overloaded Functions
Multiple functions can have the same name with different implementations. 函数重载简化了函数调用工作。

37 函数重载的例子 这些都是函数原型 #include <iostream.h>
//Overload abs( ) three ways int abs(int n); long abs(long n); double abs(double n); //prototype is neccessary for C++ compiler 这些都是函数原型

38 函数重载的例子 main( ) { cout<<"Absolute value of -10:"<<abs(-10)<<"\n"; cout<<"Absolute value of -10L:"<<abs(-10L)<<"\n"; cout<<"Absolute vallue of : " <<abs(-10.01)<<"\n";  return 0; }

39 abs( ) for ints //abs() for ints int abs(int n) {
cout<<"In interger abs( )\n"; return n<0?-n:n; }

40 abs( ) for longs long abs(long n) { cout<<"In long abs()\n";
return n<0?-n:n; }

41 abs( ) for doubles //abs( ) for doubles double abs(double n) {
cout<<"In double abs()\n"; return n<0?-n:n; }

42 1.3.7 new和delete运算符 在C语言中,使用函数malloc( ) 分配动态内存,用函数free( )释放动态内存;
在C++语言中,还可以使用运算符new 分配动态内存,用delete释放动态内存。

43 new 和 delete的简单应用 // A simple example of new and delete.
#include <iostream.h>  main( ) { int *p;   p=new int; // allocate room for an integer   // always make sure that allocate succeeded if(!p) { cout<<"Allocation error\n"; return 1; }

44 A simple example of new and delete(cont)
  cout<<"Here is integer at p: "<<*p<<"\n"; delete p; // release memory return 0; }

45 new和delete的优点 new和delete完成的功能类似于malloc( ) 与free( ),但它们有几个优点:
1) 简洁性:能自动计算所要分配的内存的大小; 2) 可靠性:编译时进行类型检查; 3) 灵活性:new和delete 运算符可以被重载。 注意:用new 申请的动态内存必须用delete 释放。

46 1.3.8  引用(reference) 引用是一个隐含指针,可以看作变量的另一个名称(别名)。 引用有三种使用方法:

47 引用作为函数参数(最重要的用法) #include <iostream.h> void f(int &n);
// declare a reference parameter using &  main() { int i=0;   f(i); // The address of variable i is passed. cout<<"Here is i's new value: "<<i<<'\n'; return 0; }

48 引用作为函数参数(继续) // f( ) now uses a reference parameter void f(int &n) {
// notice that no * is needed in the following statement n=100; //put 100 into the argument used to call f( ) }

49 指针参数和引用参数的比较 // 交换实际参数的值 // 交换实际参数的值 void swap(int &x, int &y)
{ int temp; temp = x; //保存地址x中的值 x = y; // put y into x y = temp; // put x into y } // 调用函数swap()时使用变量i和j的名字 swap(j, i); // 交换实际参数的值 void swap(int *x, int *y) { int temp; temp = *x; // 保存地址x中的值 *x = *y; // put y into x *y = temp; // put x into y } // 调用函数swap()时使用变量i和j的地址 swap(&j, &i);

50 引用参数的几个好处 当使用引用参数的时候,传递的是用作参数的变量的地址。 1) 地址被自动传递;不需要记住传递参数的地址。
2) 比指针方法更简练,清晰。 3) 当对象作为引用被传递给函数的时候,没有进行拷贝(复制)。

51 引用作为函数的返回值 // A simple example of a function returnnig a reference.
#include <iostream.h> int & f( ); int x;  main() { f( )=100; // f( ) return the address of x   cout<<x<<"\n";   return 0; }

52 引用作为函数的返回值(继续) // Return an int reference. int &f( ) {
// Return an int reference. int &f( ) { return x; // returns a reference to x }

53 独立的引用 至今没有发现独立引用的价值,在一个程序中用两个名字来描述同一个对象,可能使程序出现混乱。(应当避免)

54 习 题 1 必做题: P20: 2, 8, 9, 10 选作题:3, 4, 6


Download ppt "An Introduction to Object-Oriented Programming Using C++"

Similar presentations


Ads by Google