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<<...

 

      

posted @ 2016-05-15 15:53  zhanghouyu  阅读(160)  评论(0编辑  收藏  举报