Class & Object

Class & Object


(类 与 对象)

Encapsulation


(封装)

【例3-1】Queue(队列)


  • append(入队)
  • pop(出队)

  • 队列是否满
  • 队列是否空

使用 Queue类和对象

Queue queue;
if ( !queue.isFull() ) {
    queue.append ( 100 ) ;
}

int n ;
if ( !queue.isEmpty() ) {
    n = queue.pop ( ) ;
}
...
Queue *p = new Queue() ;
p -> append ( 100 ) ;
p = &queue ;
...

define/declare(定义/声明): Queue类 ( Queue.h )

class Queue{

public:
    void append ( int item ) ;
    int pop ( ) ;
    bool isEmpty ( ) ;
    bool isFull ( ) ;
private:
    int data[ 100] ;
    int head = 0 ;
    int tail = 0 ;
};

implement(实现) Queue类 ( Queue.cpp )

#include “Queue.h”

void Queue::append( int item ){
    data[ head ] = item;
    head = (head+1) % 100;
}
int Queue::pop(){
    tail = ( tail + 1 ) % 100 ;
    return data[ tail-1 ] ;
}
bool Queue::isEmpty(){
    return (head == tail);
};
bool Queue::isFull(){
    return ((head+1)%100 == tail);
};

【课堂练习3-1】Stack类


  • LIFO(后进先出,FILO)

  • 可容纳100个元素(int型)

  • 可判断是否为空

  • 可判断是否已满

  • push(进栈)操作

  • pop(出栈)操作

constructor/deconstuctor


(构造/析构)

【例3-2-1】改进Stack类


初始化的时候确定最大容量

Stack stack(10000);
...
Stack.h:

class Stack{
public:
    Stack(int capbility);// 构造函数
private:
    int* data;
};
在Stack.cpp中实现:

Stack::Stack(int capbility){
    data = new int[capbility];
}

或者直接在Stack.h中实现:

class Stack{
public:
    Stack(int capbility){
        data = new int[capbility];
    }
    ...
}
Point(int x, int y){
    this->x = x;
    this->y = y;
}

利用初始化列表:

Point(int x, int y):x(x),y(y) {}

单参数构造函数 实例化对象的写法

Stack s(100);
//等价于
Stack s=100;
void foo(){
    Stack s(10000);
}

???
内存泄漏!!!

【例3-2-2】改进Stack类


析构的时候回收内存

class Stack{
    public:
        Stack(int capbility){
            data = new int[capbility];
        }
        ~Stack(){ //析构函数
            delete [] data;
        }
    }
    

【课堂练习3-2】安全数组


  • 数组下标越界时,报错!

默认(缺省)构造函数

int main(){
    Point p;
    ...
}
class Point{
public:
    //无构造函数
private:
    int x, y;  //x和y为随机数
};

默认(缺省)构造函数

int main(){
    Point p;
    ...
}
class Point{
public:
    //无构造函数
private:
    int x =0 , y = 0;
};

默认(缺省)构造函数

int main(){
    Point p;
    ...
}
class Point{
public:
    //有不带参数的构造函数
    Point():x(0),y(0){}
    
private:
    int x , y ;
};

默认(缺省)构造函数

int main(){
    Point p;  // 错误!
    ...
}
class Point{
public:
    // 只有带参数构造函数,没有不带参数的构造函数
    Point(int x,int y):x(x),y(y){}
private:
    int x , y ;
};

How about 默认析构函数?

this 指针

class Point{
public:
    Point(int x,int y){
        this->x = x;
        this->y = y;
    }
private:
    int x , y ;
};

this 指针

class Point{
public:
    Point(int x,int y){
        this->x = x;
        this->y = y;
    }
private:
    int x , y ;
};

【例3-3】应用this指针

Queue q1(“青年组”),q2(“中老年组”);
Person p1("张三",20),p2("李四",50);
p1.groupTo(&q1);
p2.groupTo(&q2);

Person persons[100];
for(int i=0;i<100;i++){
    if ( persons[i].age >=45 ){
        persons[i].groupTo(&q2);
    }else{
        persons[i].groupTo(&q1);
    }
}
class Queue{
public:
    void append(Person *p);
};

class Person{
public:
    void groupTo(Queue* queue);
};

void Person::groupTo( Queue* queue ){
    this->group = queue;
    
    queue->append( ??? );
}
void Person::groupTo( Queue* queue ){

    this->group = queue;
    
    queue->append( this );
    
}

应用this指针(链式调用)

q1->append(&p1);
q1->append(&p2);

q1->append(&p1)->append(&p2);

应用this指针(链式调用)

Queue* Queue::append(Person *p){
    ...
    return this;
}

【课堂练习3-3】改进Stack

利用链表 实现 自动扩容

copy构造函数

class Stack{
public:
    Stack(Stack & old){
       ...
    }
};

copy构造函数的调用时机

Stack s1;

//显式调用copy构造函数
Stack s2 = s1;
Stack s3(s1);

copy构造函数的调用时机

void foo(Stack s){
    ...
}

Stack s1;

//隐式调用copy构造函数
foo(s1);

copy构造函数的调用时机

Stack foo(){
    Stack s;
    ...
    return s;
}
Stack s1;

//隐式调用copy构造函数
s1 = foo();

copy构造函数的调用时机

Stack s1,s2;

s2 = s1; //赋值运算,不调用拷贝构造函数

【作业3-1】

  1. 【课堂练习3-2】SafeArray
  2. 【课堂练习3-3】Stack

The End

目录