Download presentation
Presentation is loading. Please wait.
1
第六章 数据抽象-类 胡昊 南京大学计算机系软件所
2
重要内容
3
栈-过程式 #include <iostream> using namespace std; //定义栈数据类型
bool push(Stack &s, int i) { if(s.top==STACK_SIZE-1) cout << “Stack is overflow.\n”; return false; } else s.top++; s.buffer[s.top] = i; return true; bool pop(Stack &s, int &i) if(s.top==-1) cout <<“Stack is empty.\n”; i=s.buffer[s.top]; s.top--; #include <iostream> using namespace std; //定义栈数据类型 #define STACK_SIZE 100 struct Stack { int top; int buffer[STACK_SIZE]; }; void init(Stack &s) s.top = -1; }
4
栈-过程式(使用) //使用栈类型数据 Stack st; int x; init(st); //对st进行初始化。
push(st,12); //把12放进栈。 pop(st,x); //把栈顶元素退栈并存入变量x。 或, Stack st; int x; //对st进行初始化。 st.top = -1; //把12放进栈。 st.top++; st.buffer[st.top] = 12; //把栈顶元素退栈并存入变量x。 x = st.buffer[st.top]; st.top--;
5
栈-对象式 #include <iostream> using namespace std; //定义栈数据类型
bool Stack::push(int i) { if (top==STACK_SIZE-1) cout << “Stack is overflow.\n”; return false; } else top++; buffer[top]=i; return true; bool Stack::pop(int &i) if (top == -1) cout << “Stack is empty.\n”; i = buffer[top]; top--; #include <iostream> using namespace std; //定义栈数据类型 #define STACK_SIZE 100 class Stack { int top; int buffer[STACK_SIZE]; public: Stack(){top=-1;} bool push(int i); bool pop(int &i); };
6
栈-过程式(使用) //使用栈类型数据 Stack st; //自动地去调用st.Stack()对st进行初始化。 int x;
st.push(12); //把12放进栈st。 st.pop(x); //把栈顶元素退栈并存入变量x。 st.top = -1; //Error st.top++; //Error st.buffer[st.top] = 12; //Error
7
Date类 class Date { public: void set(int y, int m, int d) year = y;
month = m; day = d; } bool is_leap_year() return (year%4 == 0 && year%100 != 0) || (year%400==0); void print() cout<<year<<"."<<month<<"."<<day<<endl; private: int year,month,day; };
8
Date类(成员函数外部定义) class Date { public: void set(int y, int m, int d);
bool is_leap_year(); void print(); private: int year,month,day; }; void Date::set(int y, int m, int d) year = y; month = m; day = d; } bool Date::is_leap_year() return (year%4 == 0 && year%100 != 0) || (year%400==0); void Date::print() cout<<year<<"."<<month<<"."<<day<<endl;
9
TPoint类 class TPoint { public: void SetPoint(int x, int y);
int Xcoord() { return X ; } int Ycoord() { return Y ;} void Move(int xOffset, int yOffset) ; private: int X, Y; }; void TPoint::SetPoint(int x, int y) X=x ; Y=y ; } void Tpoint::Move(int xOffset, int yOffset) X+=xOffset; Y+=yOffset;
10
对象的操作 class A { public: int x; void f() { 允许访问:x,y,z,f,g,h } private:
int y; void g() { 允许访问:x,y,z,f,g,h } protected: int z; void h() { 允许访问:x,y,z,f,g,h } }; ...... A a; a.x = 1; //OK a.f(); //OK a.y = 1; //Error a.g(); //Error a.z = 1; //Error a.h(); //Error
11
对Date类的对象访问 #include <iostream> using namespace std;
#include “Date.h” int main() { int y, m, d; cout<<“请输入年、月、日:“; cin>>y>>m>>d; Date some_date; //创建一个Date类的对象d some_date.set(y,m,d); //设置对象d的日期值 some_date.print(); //输出d所表示的日期 if(some_date.is_leap_year()) cout<<“是闰年\n”; else cout<<“不是闰年\n”; return 0; };
12
对象的操作 class A { public: int x; void f() { 允许访问:x,y,z,f,g,h } private:
int y; void g() { 允许访问:x,y,z,f,g,h } protected: int z; void h() { 允许访问:x,y,z,f,g,h } }; ...... A a; a.x = 1; //OK a.f(); //OK a.y = 1; //Error a.g(); //Error a.z = 1; //Error a.h(); //Error
13
栈-链表实现 #include <iostream> #include <cstdio>
bool Stack::push(int i) { Node *p=new Node; if (p==NULL) cout << “Stack is overflow.\n”; return false; } else p->content=i; p->next=top; top=p; return true; bool Stack::pop(int &i) if (top == NULL) cout << “Stack is empty.\n”; Node *p= top; top=top->next; i=p->content; delete p; #include <iostream> #include <cstdio> using namespace std; //定义栈数据类型 class Stack { struct Node int content; Node *next; } *top; public: Stack(){top=NULL;} bool push(int i); bool pop(int &i); };
14
this指针 class A { public: void g(int i) { x = i; } private: int x,y,z;
}; A a,b; 例如,对于下面的成员函数调用: a.g(1);编译程序将会把它编译成: A::g(&a,1);
15
this指针 void func(A *p) { ...... } class A { public: int x;
{ } class A { public: int x; void f() { func(?); } void q(int i) { x = i; f(); } }; A a,b; 如果要求: 当调用a.f()时,在A::f中调用func(&a); 当调用b.f()时,在A::f中调用func(&b); 那么,A::f中调用函数func的参数应该如何写呢?
16
构造函数调用 class A { ...... public: A(); A(int i); A(char *p); };
{ public: A(); A(int i); A(char *p); }; A a1; //调用默认构造函数。也可写成:A a1=A(); 但不能写成:A a1(); A a2(1); //调A(int i),也可写成:A a2=A(1); 或 A a2=1; A a3(“abcd”); //调A(char *),也可写成:A a3=A(“abcd”); 或 A a3=“abcd”; A a[4]; //调用a[0]、a[1]、a[2]、a[3]的A() A b[5]={A(),A(1),A("abcd"),2,"xyz"}; //调用b[0]的A()、b[1]的A(int)、//b[2]的A(char *)、 //b[3]的A(int)和b[4]的A(char *)。 A *p1=new A; //调用默认构造函数。 A *p2=new A(2); //调A(int i)。 A *p3=new A("xyz"); //调A(char *)。 A *p4 =new A[20]; //创建动态对象数组时只能调用各对象的默认构造函数。
17
常成员,引用成员和初始化列表 class A { int x; const int y;
int &z=y; //Error,这里是说明,而不是定义。 public: A() x = 0; //OK y = 1; //Error,y是常量成员,其值不能改变。 } }; class A { int x; const int y; int& z; public: A(): y(1),z(x) //成员初始化表 x = 0; } };
18
析构函数 class A { int x; public: A(); ~A(); //析构函数 ...... };
19
字符串类的定义(1) char &char_at(int i) { if(i<0 || i>= strlen(str))
cerr << "超出字符串范围!\n"; exit(-1); } return str[i]; char *get_str() { return str; } String ©(const char *p) char *p1=new char[strlen(p)+1]; strcpy(p1,p); delete []str; str = p1; return *this; String ©(const String &s) { return copy(s.str); } #include <cstring> #include <cstdlib> #include <iostream> using namespace std; class String { char *str; public: String(){ str=NULL;} String(const char *p) str = new char[strlen(p)+1]; strcpy(str,p); } ~String() delete []str; str = NULL; int length(){ return strlen(str);}
20
字符串类的定义(2) int main() { String s1; String s2("abcdefg");
s1.copy("xyz"); s2.append(s1); for (int i=0; i<s2.length(); i++) if(s2.char_at(i) >= 'a' && s2.char_at(i) <= 'z') s2.char_at(i) = s2.char_at(i)-'a'+'A'; } if (s2.compare("ABCDEFGXYZ") == 0) cout << "OK\n"; cout << s1.get_str() << endl << s2.get_str() << endl; return 0; String &append(const char *p) { char *p1=new char[strlen(str)+strlen(p)+1]; strcpy(p1,str); strcat(p1,p); delete []str; str = p1; return *this; } String &append(const String &s) { return append(s.str); } int compare(const char *p) { return strcmp(str,p); } int compare(const String &s) { return strcmp(str,s.str); } };
21
成员对象初始化 class A { int m; public: A() { m = 0; } A(int m1) { m = m1; }
}; class B int n; A a; B() { n = 0; } B(int n1) { n = n1; } B::B(int n1, int m1): a(m1) { n = n1; } B b1,b2(1), b3(1,2);
22
拷贝构造函数 A::A(const A& a) class A { x = a.x; { y = a.y; int x,y;
p = new char[strlen(a.p)+1]; strcpy(p,a.p); } class A { int x,y; char *p; public: A(char *str) x = 0; y = 0; p = new char[strlen(str)+1]; strcpy(p,str); } ~A() { delete []p; } ...... };
23
拷贝构造函数 class A { ...... }; class B int z; A a; public: B();
B(const B& b): a(b.a) //调A的拷贝构造函数用b.a对a进行初始化 z = b.z; }
24
静态成员 class A { static int obj_count; …... public: A() { obj_count++; }
static int get_num_of_objects() { return obj_count; } }; int A::obj_count=0; ...... cout << A::get_num_of_objects() << endl;
25
友元 class Point { public: Point(double xx, double yy) {x=xx; y=yy; }
void Getxy(); friend double Distance(Point &a, Point &b); private: double x, y; }; void Point::Getxy() cout<<”(“<<x<<”,”<<y<<”,”<<endl; } double Distance(Point &a, Point &b) double dx=a.x—b.x; double dy=a.y—b.y; return sqrt(dx*dx+dy*dy);
Similar presentations