保证线程安全的方法:
线程安全,互斥量加信号锁,原子操作
无锁队列(锁锁住的时候不进行用户态和内核态的切换)
智能指针不能保证线程安全
什么时候专门对析构函数释放所创建对象的空间:
析构函数不能释放对象创建的空间,析构函数释放所占的资源(构造的时候生成的堆资源,在构造的时候定义了一个文件指针,指向了文件流对象,等到释放的时候,关闭文件流对象)
如何释放对象所占的空间:
先明确对象创建在哪个位置点
主函数结束,主函数的空间要回收
析构函数是释放对象所占的资源
空间是由系统进行回收的
class Object
{
FILE* fp;
public:
Object(char* filename)
{
fp = fopen(filename,"w");
}
~Object()
{
fclose(fp);
fp = NULL;
}
};
Object obja;//.data,先于主函数创建,等到整个程序结束的时候,调用析构函数,空间由系统管理
int main()
{
Object objb;//.stack,函数调用,给它分配空间,调动构造函数创建对象,空间由于主函数的消失而回收
Object *p = new Object();//.heap
delete p;//1.调动析构函数;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
{}
};
对象在内存中的表达
#include"stdio.h"
#include<stdlib.h>
#include<assert.h>
#define SEQ_INIT_SIZE 10
class SeqList
{
int data[SEQ_INIT_SIZE];
int maxsize;
int cursize;
public:
SeqList():maxsize(SEQ_INIT_SIZE),cursize(0)
{
}
~SeqList()
{
}
};
int main()
{
SeqList seqa;
}
#define SEQ_INIT_SIZE 10
#define SEQ_INC_SIZE 2
class SeqList
{
private:
int *data;
int maxsize;
int cursize;
SeqList(const SeqList& seq) = delete;
//C 11 ,防止进行拷贝构造
SeqList& operator=(const SeqList& seq) = delete;
public:
SeqList():maxsize(SEQ_INIT_SIZE),cursize(0)
{
data = (int*)malloc(sizeof(int)*maxsize);
}
~SeqList()
{
free(data);
data = NULL;
}
//缺省赋值语句
//为什么此处不能用列表方式进行:因为对象只能构建一次以及对象里面的数据成员只能构建一次
//SeqList& operator=(const SeqList& seq)
// {
//if(this != &seq)
//{
//maxsize = seq.maxsize;
//cursize = seq.cursize;
//memcpy(data,seq.data,sizeof(data));
//}
//return *this;
//}
//缺省拷贝构造函数
//SeqList(const SeqList& seq):maxsize(seq.maxsize),cursize(seq.cursize)//加const使程序的通用性更好
//{
//memcpy(data,seq.data, sizeof(data));
// memcpy(data,seq.data, sizeof(int)*cursize);
//}
};
SeqList fun(SeqList seq)
{
SeqList seqx;
return seqx;
}
int main()
{
SeqList seqa;
SeqList seqb(seqa);
SeqList seqc;
seqc = seqb;
fun(seqa);
}
构造函数设置为私有时,如何创建全局对象?
静态函数的使用方式
是否可以把析构函数设计为私有?不可以,对象无法死亡
#define SEQ_INIT_SIZE 10
#define SEQ_INC_SIZE 2
class SeqList
{
private:
int *data;
int maxsize;
int cursize;
public:
SeqList():data(NULL),maxsize(SEQ_INIT_SIZE),cursize(0)
{
data = (int*)malloc(sizeof(int)*maxsize);
}
SeqList(const SeqList& seq)
{
data = seq.data;
maxsize = seq.maxsize;
cursize = seq.cursize;
}
SeqList& operator = (const SeqList& seq)
{
if(this != &seq)
{
data = seq.data;
maxsize = seq.maxsize;
cursize = seq.cursize;
}
return *this;
}
~SeqList()
{
free(data);
data = NULL;
}
};
int main()
{
SeqList seqa;
SeqList seqb(seqa);
return 0;
}
//空间释放两次,导致程序崩溃
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(const Vector& vec):
~Vector()
{
free(first);
_first = _last = _end;
}
};
int main()
{
Vector vec;
}
vec._last - vec._first = 元素的个数;cursize
vec._end - vec._first = 容量的大小;maxsize
#define SEQ_INIT_SIZE 10
#define SEQ_INC_SIZE 2
class SeqList
{
private:
int *data;
int maxsize;
int cursize;
public:
SeqList():data(NULL),maxsize(SEQ_INIT_SIZE),cursize(0)
{
data = (int*)malloc(sizeof(int)*maxsize);
}
SeqList(const SeqList& seq)
{
data = seq.data;
maxsize = seq.maxsize;
cursize = seq.cursize;
}
SeqList& operator = (const SeqList& seq)
{
if(this != &seq)
{
data = seq.data;
maxsize = seq.maxsize;
cursize = seq.cursize;
}
return *this;
}
~SeqList()
{
free(data);
data = NULL;
}
};
int main()
{
SeqList seqa;
SeqList seqb;
seqb = seqa;
return 0;
}//会发生内存泄漏
什么时候要写自己的拷贝构造函数和重载赋值语句
在类设计的过程中,设计出指针或者设计出指向内核态对象,文件具名指针,线程,信号量,互斥量,写自己的拷贝构造函数和重载赋值语句
指针通过new或者malloc使用堆区空间
#define SEQ_INIT_SIZE 10
#define SEQ_INC_SIZE 2
class SeqList
{
private:
int *data;
int maxsize;
int cursize;
public:
SeqList():data(NULL),maxsize(SEQ_INIT_SIZE),cursize(0)
{
data = (int*)malloc(sizeof(int)*maxsize);
}
SeqList(const SeqList& seq)
{
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)
{
data = seq.data;
maxsize = seq.maxsize;
cursize = seq.cursize;
}
return *this;
}
~SeqList()
{
free(data);
data = NULL;
}
};
int main()
{
SeqList seqa;
SeqList seqb;
seqb = seqa;
return 0;
}
#define SEQ_INIT_SIZE 10
#define SEQ_INC_SIZE 2
class SeqList
{
private:
int *data;
int maxsize;
int cursize;
public:
SeqList():data(NULL),maxsize(SEQ_INIT_SIZE),cursize(0)
{
data = (int*)malloc(sizeof(int)*maxsize);
}
SeqList(const SeqList& seq)
{
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)*cursize);
memcpy(data,seq.data, sizeof(int)*cursize);
maxsize = seq.maxsize;
cursize = seq.cursize;
}
return *this;
}
~SeqList()
{
free(data);
data = NULL;
}
};
int main()
{
SeqList seqa;
SeqList seqb;
seqb = seqa;
return 0;
}
对于内置类型,malloc和delete可以混用,new和free可以混用
对于自定义类型,是不允许的
class String
{
char* str;
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<<(const String* const this,ostream& out)
ostream& operator<<(ostream& out)const
{
if(str != NULL)
{
out<<str;
}
return out;
}
String(const String& s)
{
str = s.str;
}
//浅拷贝,或者系统提供的拷贝构造函数
//如何把浅拷贝变为深拷贝
//s1<<cout;
//s1.operator<<(cout);
//operator<<(&s1,cout);
};
//const只能修饰this指针
ostream& operator<<(ostream& out,const String& s)
{
s << out;
//s.operator<<(&s,out);
//operator<<(&s,out);
return out;
}
int main()
{
String s1("yhpinghello");
cout<<s1<<endl;
operator<<(cout,s1);
}
int main()
{
String s1("yhpinghello");
s1<<cout;
}
int main()
{
String s1("yhpinghello");
cout<<s1<<endl;
cout<<12<<endl;
cout<<"yhping"<<endl;
}
class String
{
char* str;
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;
}
String(const String& s)
{
str = s.str;
}//浅拷贝
//如何把浅拷贝变为深拷贝
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;
}
String& operator=(const String& s)
{
if(this != &s)
{
//delete[] str;
//str = new char[strlen(s.str)+1];
//strcpy(str,s.str);
delete[]str;
new (this)String(s);
}
return *this;
}
};
int main()
{
String s1("yhping");
String s2("hello");
s2 = s1;
}
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;
}
//如何把浅拷贝变为深拷贝
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;
}
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);//p所指向的空间没有释放,发生内存泄漏
}
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);
}
//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);//p所指向的空间没有释放,发生内存泄漏
//}
String(String&& s);
String& operator=(String&& s);
};
ostream& operator<<(ostream& out,const String& s)
{
s << out;
return out;
}
String operator+(const char*p,const String& s)
{
return String(p)+s;
}
String fun()
{
String s2("yhping");
return s2;
}
int main()
{
String s1;
s1 = fun();
return 0;
}
int main()
{
String s1("yhping");
String s2("hello");
String s3;
s3 = s1 + s2;
s3 = s1 + "newdata";
s3 = "newdata" + s1;
}
左值,将亡值,右值,纯右值
整个程序在运行过程中,空间利用率如何达到最大化?
虚拟内存,堆区的管理
CAS问题
无锁
除了加锁还有其他方式可以实现线程安全吗?
无锁队列,无锁栈