0
点赞
收藏
分享

微信扫一扫

C++:线上课程1_18(构造函数和赋值函数)

GG_lyf 2022-03-15 阅读 49

C++概述


C++调用函数顺序

class Object
{};

Object obja;//.data
int main()
{
    Object objb; //.stack

    Object* p = new Object(); //.heap

    delete p;//1.调用析构函数~Object 2.把堆空间还给系统

    return 0;
}

C++切片问题

继承关系和公有继承,子对象赋值给父对象才会产生切片问题,父对象不能赋值给子对象

class Object
{
    int value;
public:
    Object(int x=0) :value(x) {}
};
class Base :public Object
{
    int num;
public:
    Base(int x=0):Object(x+10),num(x) {}
};

在这里插入图片描述


构造函数

1.局部对象内存分配图

#define _CRT_SECURE_NO_WARNINGS
#include"stdio.h"
#include<iostream>
#include<assert.h>
#define SEQ_INIT_SIZE 10
class SeqList
{
    int data[SEQ_INIT_SIZE];//40
    int maxsize;//4
    int cursize;//4
public:
    SeqList() :maxsize(SEQ_INIT_SIZE), cursize(0)
    {
    }
    ~SeqList() {}
};
int main()
{
    SeqList seqa;
    return 0;
}

内存分配图

2.为什么系统要提供缺省构造函数和缺省赋值语句?

因为对象在整个函数生存期之内要被构建,所以要调用缺省构造函数。每个对象生存期结束时候要释放资源,所以要调用析构函数。

SeqList fun(SeqList seq)
{
    SeqList seqx;
    return seqx;
}
int main()
{
    SeqList seqa;
    SeqList seqb(seqa);
    SeqList seqc;
    seqc = seqb;
    return 0;
}

(1)在对象生存期过程中,要用一个对象初始化另一个对象,要调用缺省构造函数,函数在对象生存期内会使用。

(2)列表初始化只能使用在构造函数和拷贝构造函数里面,其他函数不能使用

(3)不允许使用一个对象初始化另一个对象应该如何操作?
将构造函数声明和拷贝构造函数声明加入私有部分,程序不在自动生成构造函数,所有对象都不能进行拷贝构造,只能构建对象和析构对象,不能用一个对象初始化另一个对象,两对象也不能进行赋值。

(4)是否可以将析构函数设置为私有?
不可以,对象虽然可以创建,但是不能释放。所有类的构造函数,拷贝构造函数,赋值语句重载函数,析构函数都不能随便设置私有。

3.对象内存分配图

#define SEQ_INIT_SIZE 10
#define SEQ_INC_SIZE  2
class SeqList
{
    int* data;
    int maxsize;
    int cursize;
public:
    SeqList() :maxsize(SEQ_INIT_SIZE), cursize(0)
    {
        data = (int*)malloc(sizeof(int) * maxsize);
    }
    ~SeqList() 
    {
        free(data);
        data = NULL;
    }
};


class Vector
{
    int* _first;
    int* _last;
    int* _end;
public:
    Vector() :_first(NULL), _last(NULL), _end(NULL)
    {
        _first = (int*)malloc(sizeof(int) * SEQ_INC_SIZE);
        _last = _first;
        _end = _first + SEQ_INIT_SIZE;
    }
    ~Vector()
    {
        free(_first);
        _first = _last = _end();
    }
};
int main()
{
    SeqList seqa;
    //SeqList seqb(seqa);不允许编译通过,因为seqa和sseqb指向同一块内存,导致释放两次,程序奔溃
    SeqList seqb;
    //seqb=seqa;不允许编译通过,会产生内存泄漏。当seqa和seqb指向同一块内存会导致同一块内存释放两次,然后seqb初始指向的堆内存没有释放,造成内存泄漏
    return 0;
}

在这里插入图片描述
在这里插入图片描述

vec._last-vec._first=maxsize;//元素个数大小
vec._end-vec._first=cursize;//容量大小

4.何时需要自己定义拷贝构造函数和赋值语句?

在类的设计过程中,设计指针和指向内核态时,设计线程,要重新定义自己的拷贝构造函数和赋值语句。

5.深拷贝

    //缺省拷贝构造函数
    SeqList(const SeqList& seq)
    {
        //data = seq.data;
        //浅拷贝构造
        maxsize = seq.maxsize;
        cursize = seq.cursize;
        //深拷贝构造
        data = (int*)malloc(sizeof(int) * seq.maxsize);
        memcpy(data, seq.data, sizeof(int) * seq.cursize);
    }
    //缺省赋值函数
    SeqList& operator=(const SeqList& seq)
    {
        if (this != &seq)
        {
            //释放原有函数
            free(data);
            data = (int*)malloc(sizeof(int) * seq.maxsize);
            memcpy(data, seq.data, sizeof(int) * seq.cursize);
            maxsize = seq.maxsize;
            cursize = seq.cursize;
        }
        return *this;
    }

const只能修饰常方法,全局变量没有this指针

#define _CRT_SECURE_NO_WARNINGS
#include"stdio.h"
#include<iostream>
#include<stdlib.h>
#include<assert.h>
#include<string.h>
using namespace std;

class String
{
    char* str;
    String(char* p, int)
    {
        str = p;
    }
public:
    String(const char* p = NULL) :str(NULL)
    {
        if (p != NULL)
        {
            str = new char[strlen(p) + 1];
            strcpy(str, p);
        }
        else
        {
            str = new char[1];
            *str = '\0';
        }
    }
    ~String()
    {
        if (str != NULL)
        {
            delete[] str;
        }
        str = NULL;
    }
    //类的成员函数,
    ostream& operator<<(ostream& out) const
    {
        if (str != NULL)
        {
            out << str << endl;
        }
        return out;
    }
    String(const String& s) :str(NULL)
    {
        str = new char[strlen(s.str + 1)];
        strcpy(str, s.str);
    }
    //缺省赋值语句
    String& operator=(const String& s)
    {
        if (this != &s)
        {
            delete[]str;
            str = new char[strlen(s.str) + 1];
            strcpy(str, s.str);
        }
        return *this;
    }
    //s3=s1+s2;
    String operator+(const String& s) const
    {
        char* p = new char[strlen(this->str) + strlen(s.str) + 1];
        strcpy(p, this->str);
        strcat(p, s.str);
        return String(p, 1);//调用私有拷贝构造函数
    }
    //s3=s1+"newdata";
    String operator+(const char* s) const
    {
        char* p = new char[strlen(this->str) + strlen(s) + 1];
        strcpy(p, this->str);
        strcat(p, s);
        return String(p, 1);

        //return *this+String(s);
    }
};
ostream& operator<<(ostream& out, const String& s)
{
    s << out;
    //s.operator<<(out);
    //operator<<(&s, out);
    return out;
}
//s3="newdata"+s1;
String operator+(const char* p, const String& s)
{
    return String(p) + s;
}

int main()
{
    String s1("hxy");
    String s2("hello");
    String s3;
    //s3=s1+s2;
    //s3=s1+"newdata";
    //s3="newdata"+s1;
}
举报

相关推荐

0 条评论