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