C++面向对象高级编程(上) 第二周笔记 GeekBand
拷贝构造、拷贝赋值以及析构函数:类带pointer一定要写拷贝构造和拷贝赋值
普通构造函数:
inline string::string(const char* cstr=0){
if(cstr){
m_data=new char[strlen(cstr)+1];//strlen计算string长度不包括末尾的'\0'
strcpy(m_data,cstr) ;
}
else{
m_data=new char[1];
*m_data='\0';
}
}
拷贝构造函数:
inline string::string(const string& str){
m_data=new char[strlen(str.m_data)+1];
strcpy(m_data,str.m_data);
}
深拷贝:拷贝pointer指向的内容
浅拷贝:只拷贝pointer,相当于给pointer设一个别名。
拷贝赋值:
inline string::operator=(const string& str){
if(this==&str)//检测自我赋值,没有会出错,而不仅是关乎效率的问题
return *this;
delete[] m_data;
m_data=new char[strlen(str.m_data)+1];
strcpy(m_data,str.m_data);
return *this;
}
析构函数:
inline string::~string(){
delete[] m_data;//delete删除m_data指向的内存空间
}
stack和heap:
每个函数都有一个stack,用于存放参数,返回地址,local object。stack存在于他的作用域。
heap由操作系统提供的global空间,由new取得,由delete释放
static object在作用域之后仍然存在,直到整个程序结束1。
global object:生命期在整个程序
new:先分配memory,再调用构造函数
complex* pc=new complex(1,2);
编译器转化为:
void* mem=operator new(sizeof(complex));分配内存,内部调用malloc(n)
pc=static_cast<complex*>(mem);转型
pc->complex::complex(1,2);构造函数//complex::complex(pc,1,2);
this
delete:先调用析构函数,再释放memory
string* ps=new string("hello");
delete ps;
编译器转化为:
string::~string(ps);析构函数
operator delete(ps);释放内存//内部调用free(ps)
static:
(1)static成员数据:例如像银行IT系统中的利率,并不是每个用户拥有一份,而是所有账户都有统一的利率,可以加static,表明所有账户共有相同利率。
static成员数据要在class外定义。
例:class Account{
public:
static double m_rate;
static void set_rate(const double& x){m_rate=x;}
}
double Account::m_rate=8.0;
(2)static成员函数:没有this pointer。只能处理static类型的成员数据。
调用static函数的方式:
a.通过object调用,和普通成员函数一样。例如;
Account a;
a.set_rate(7.0);
b.通过class name调用,例如:
Account::set_rate(5.0);
单例模式:
class A{
public:
static A& getInstance(){return a;};
setup(){...}
private:
A();
static A a;
}
调用函数setup方式:A::getInstance().setup();
缺点:如果没有用到类A的唯一对象a,由于a在创建类是就存在并一直存在,将造成内存空间的浪费。
更好的写法:
class A{
public:
static A& getInstance();
setup(){...}
private:
A();
}
A& A::getInstance(){
static A a;
return a;
}
调用函数setup方式:A::getInstance().setup();
调用getInstance后a一直存在。
namespace:
(1)using namespace std;
cout<<...
cin>>...
(2)using std::cout;
cout<<...
(2)std::cout<<...