第三章 类和对象

3.1 类和对象、this指针

this指针 :一个类可以产生很多对象,共享一套成员方法,this指针用来区分不同成员方法。

3.2 构造函数和析构函数
#include "iostream"

using namespace std;

class SeqStack {
public:
    SeqStack(int size = 5) {    //构造函数
        cout << this <<"我是构造函数" <<endl;
        _data = new int[size];
        _top = -1;
        _size = size;
    }
    ~SeqStack(){        //析构函数
        cout <<this << "我是析构函数" <<endl;
        delete[] _data;
        _data = nullptr;
    }

    // void init(int size = 5) {
    //     _data = new int[size];
    //     _top = -1;
    //     _size = size;
    // }
    // void release() {
    //     delete[] _data;
    //     _data = nullptr;
    // }
    void push(int x) {
        if (_top == _size - 1) {
            resize();   //栈满执行扩容操作
        }
        _data[++_top] = x;
    }
    void pop() {
        if (_top == -1) {
            return;
        }
        --_top;
    }
    bool empty() {
        return _top == -1;
    }
    int top() {
        return _data[_top];
    }

private:
    int *_data; //动态开辟数组,存储顺序栈的元素
    int _top;   //栈顶指针
    int _size;  //顺序栈的大小
    void resize() {
        int *new_data = new int[_size*2];
        for (int i =0;i<_size;++i) {
            new_data[i] = _data[i];
        }
        delete[] _data;
        _data = new_data;
        _size *= 2;
    }
};
SeqStack s2;
int main() {
    SeqStack *ps = new SeqStack(12);    //先调用malloc(sizeof(SeqStack)),然后调用SeqStack()
    ps->push(10);
    ps->push(20);
    ps -> pop();
    cout << ps->top() << endl;
    delete ps;     //先调用~SeqStack(),然后调用free(ps)

    SeqStack s;
    //s.init(5);
    for (int i = 0; i < 10; ++i) {
        s.push(i);
    }
    while (!s.empty()) {
        cout << s.top() << " ";
        s.pop();
    }

    SeqStack s1(20);
    //s.release();
    return 0;
}
3.3 对象的深拷贝和浅拷贝

浅拷贝与深拷贝的区别:

浅拷贝:在拷贝的对象成员有占用外部资源时,两个指针同时指向同一块内存地址,析构函数在释放时会重复释放,后面释放的是野指针,导致程序崩溃。

深拷贝:会为拷贝的对象重新开辟一片内存空间,两个指针指向的是不同的地址。

3.4 拷贝构造函数的应用实践
#include "iostream"

using namespace std;

class Queue{
public:
    //构造函数
    Queue(int size=5){
        _data = new int[size];
        _front = _rear = 0;
        _size = size;
    }
    Queue(const Queue &q) {
        _data = new int[_size];
        _front = q._front;
        _rear = q._rear;
        _size = q._size;
        for (int i = _front;i!=_rear;i=(i+1)%_size) {
            _data[i] = q._data[i];
        }
    }
    Queue& operator=(const Queue &q){
        if(this == &q) {
            return *this;
        }
        delete[] _data;
        _data = new int[_size];
        _front = q._front;
        _rear = q._rear;
        _size = q._size;
        for (int i = _front;i!=_rear;i=(i+1)%_size) {
            _data[i] = q._data[i];
        }
        return *this;
    }
    //析构函数
    ~Queue() {
        delete[] _data;
        _data = nullptr;
    }
    bool empty() {
        return _front == _rear;
    }
    bool full() {
        return (_rear+1)%_size == _front;
    }
    void push(int x) {
        if(full()) {
            resize();
        }
        _data[_rear] = x;
        _rear = (_rear+1)%_size;
    }
    void pop() {
        if(empty()) {
            return;
        }
        _front = (_front+1)%_size;
    }
    int front() {
        return _data[_front];
    }


private:
    int *_data;
    int _front;
    int _rear;
    int _size;
    void resize(){
        int num = 0;
        int *_new_data = new int[_size*2];
        for(int i=_front;i!=_rear;i=(i+1)%_size) {
            _new_data[num++] = _data[i];
        }
        delete[] _data;
        _data = _new_data;
        _front = 0;
        _rear = num;
        _size *=2;
    }
};

int main() {
    Queue q1;
    for (int i=0;i<15;++i) {
        q1.push(rand()%100);
    }
    while(!q1.empty()) {
        cout << q1.front() << " ";
        q1.pop();
    }

    Queue q2 = q1;
    return 0;

}
3.5 构造函数的初始化列表
#include "iostream"

using namespace std;

class Test {
public:
    Test(int data = 10):mb(data),ma(mb) {

    }
    void show() {
        cout << ma << " " << mb << endl;
    }
private:
    //成员变量的初始化和他们定义的顺序有关,与构造函数的初始化列表顺序无关
    int ma;
    int mb;
};
int main() {
    Test t;
    t.show();
    return 0;
}
3.6 类的各种成员方法及其区别
  • 普通的成员方法:=>编译器会添加一个this指针形参变量。

1.属于类的作用域;2.调用该方法时,需要依赖一个对象(常量对象无法调用);3.可以任意访问对象的私有成员。

  • static静态成员方法:=>不会生成this指针。

1.属于类的作用域;2.用类名作用域来调用该方法;3.可以任意访问不依赖对象的的成员,如static静态成员变量。

  • const常成员方法:=> const Student *this

1.属于类的作用域;2.调用依赖一个对象,普通对象或常量对象都可以调用;3.可以任意访问对象的私有成员,但只能读,而不能写。

#include <string.h>

#include "iostream"
using  namespace std;

class Student {
public:
    Student(const char *name,int age,char sex,float height,char *address)
    :_age(age),
    _sex(sex),
    _height(height)
    {
        strcpy(_name,name);
        strcpy(_address,address);
        _count++;
    }
    void show() {
        cout << "姓名:" << _name << endl;
        cout << "年龄:" << _age << endl;
        cout << "性别:" << _sex << endl;
        cout << "身高:" << _height << endl;
        cout << "家庭地址:" << _address << endl;
    }
    void show()const {      //调用方法时只有读操作,没有写操作时,一律写成const常成员方法。
        cout << "姓名:" << _name << endl;
        cout << "年龄:" << _age << endl;
        cout << "性别:" << _sex << endl;
        cout << "身高:" << _height << endl;
        cout << "家庭地址:" << _address << endl;
    }  //普通成员方法,生成this指针
    static void showStudentcount() {
        cout << "总共学生数量为:" << _count << endl;   //打印所有学生共享的信息
    }   //静态成员方法,不生成this指针
private:
    char _name[20];
    int _age;
    char _sex;
    float _height;
    char _address[20];
    static int _count;  //不属于对象,而属于类级别的,用来记录所有产生的新对象的数量
};

int Student::_count = 0;    //static成员变量要在类外进行定义并初始化

int main () {
    Student s1("lmh",24,'m',178.5,"陕西省咸阳市兴平市xx村");
    Student s2("xy",23,'m',176.0,"重庆市开州区");
    Student s3("zjw",23,'m',176.5,"陕西省渭南市");

    s1.show();
    s2.show();
    s3.show();
    Student::showStudentcount();

    const Student s4("zjw1",23,'m',176.5,"陕西省渭南市");
    s4.show();
    return 0;
}
3.7 指向类成员的指针

指向类成员方法的指针、指向类成员变量的指针,必须加上相应的对象才能调用。

#include "iostream"
using  namespace std;

class Test {
public:
    void func1() {
        cout << "func1" << endl;
    }
    int ma;
    static int mb;
};
int Test::mb;

int main() {
    Test t1;
    void(Test::*pfunc)() = &Test::func1;
    (t1.*pfunc)();		//指针调用类成员方法

    int Test::*p = &Test::ma;
    Test t;
    t.*p = 20;			//指针调用类成员变量
    cout << t.*p << endl;
    int *p1 = &Test::mb;
    *p1 = 30;
    cout << *p1<<endl;

    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值