GeekBand C++面向对象高级编程(上)第二周笔记

2017-01-15  本文已影响0人  悄悄地2019

第二周主要学习的是 class with pointer member,通过以String Class的设计来学习

String类最后要实现如下功能

  String s1 ();
  String s2 ("hello");
  String s3 (s1); // 拷贝构造
  
  s3 = s2; // 拷贝赋值

编译器会给每个类默认提供拷贝构造和拷贝赋值的函数,通过一个byte一个byte的拷贝。而对于类中有指针的情况,需要自己来实现这两个函数,避免和新产生的对象指向堆中内存的同一个地址

Big Three 三个特殊函数

class String {
public:
    String(const char* cstr = 0); // 构造函数
    String(const String& str); // 拷贝构造
    String& operator=(const String& str); // 拷贝赋值
    ~String(); // 析构函数
    char* get_c_str() const { return m_data; }
private:
    char* m_data;
};

下面来看各个函数的实现

// 构造函数
inline String::String(const char *cstr) {
    if (cstr) {
        m_data = new char[strlen(cstr) + 1];
        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);
}
// 拷贝赋值
inline String &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;
}

最后为了方便输出String,重载<<操作符

std::ostream& operator << (std::ostream &os, const String &str) {
    os<<str.get_c_str();
    return os;
}

堆、栈 内存管理

{
  Complex c1(1, 2); // 这种方式变量是创建在函数的栈上的
  Complex* p = new Complex(3); // 创建一个复数,初值是3,而值是创建在堆上的,动态获得,需要手动释放
}

stack object 的生命周期:只要离开作用域,就结束了。c1便是stack object,又称为auto object,因为它会被『自动』清理
static local object的生命周期:如果在c1前加上static关键字,则其在离开作用域后仍然存在,直到整个程序结束
global object 的生命周期:在任何大括号之外的地方声明的,也可视为一种static object,在整个程序结束后被清理
heap object 的生命周期:其生命在被delete时结束,如果忘记delete,将会造成memory leak,当作用域结束,指针所指向的heap object仍然存在,但指针的生命已经结束了

new: 先分配memory,再调用ctor

new 操作编译器将会分解为3个动作,1. 分配内存 2. 对指针做类型转换 3. 执行构造函数

delete: 先调用dtor,再释放memory

delete 操作编译器将会分解为2个动作,1. 执行dtor 2. 释放内存

补充的知识点

通过static来实现单例模式栗子

class A{
public:
    static A& getInstance() {
        static A instance;
        return instance;
    };
    void setup();
private:
    A();
    A(const A& other);
};
A::getInstance().setup();
上一篇下一篇

猜你喜欢

热点阅读