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;
}










