跳转至

13 Smart Pointer

说明

本文档仅涉及部分内容,仅可用于复习重点知识

1 UCObject

#ifndef UC_OBJECT_H
#define UC_OBJECT_H

#include <assert.h>

class UCObject {
public:
    UCObject();
    virtual ~UCObject();
    UCObject(const UCObject& other);

    void increase();
    void decrease();
    int get_ref_count() const;

private:
    int m_ref_count;
};

#endif
#include "uc_object.h"

UCObject::UCObject() : m_ref_count(0) {}

UCObject::~UCObject() {
    assert(m_ref_count == 0);
}

UCObject::UCObject(const UCObject& other) : m_ref_count(0) {}

void UCObject::increase() {
    m_ref_count++;
}

void UCObject::decrease() {
    assert(m_ref_count > 0);
    m_ref_count--;
    if (m_ref_count == 0) {
        delete this;
    }
}

int UCObject::get_ref_count() const {
    return m_ref_count;
}

2 StringRep

#ifndef STRING_REP_H
#define STRING_REP_H

#include "uc_object.h"

class StringRep : public UCObject {
public:
    StringRep(const char* str);
    ~StringRep();
    StringRep(const StringRep& other);

    int length() const;
    int equal(const StringRep& other) const;
    const char* get_chars() const;

private:
    char* m_chars_ptr;

    void operator=(const StringRep& other);
};

#endif
#include "string_rep.h"

#include <cstring>

StringRep::StringRep(const char* str) : UCObject() {
    if (str) {
        int len = strlen(str) + 1;
        m_chars_ptr = new char[len];
        strcpy(m_chars_ptr, str);
    } else {
        m_chars_ptr = new char[1];
        m_chars_ptr[0] = '\0';
    }
}

StringRep::~StringRep() {
    delete[] m_chars_ptr;
}

StringRep::StringRep(const StringRep& other) : UCObject() {
    int len = other.length() + 1;
    m_chars_ptr = new char[len];
    strcpy(m_chars_ptr, other.m_chars_ptr);
}

int StringRep::length() const {
    return strlen(m_chars_ptr);
}

int StringRep::equal(const StringRep& other) const {
    return strcmp(m_chars_ptr, other.m_chars_ptr) == 0;
}

const char* StringRep::get_chars() const {
    return m_chars_ptr;
}

void StringRep::operator=(const StringRep& other) {
    if (this == &other) {
        return;
    }
    delete[] m_chars_ptr;
    int len = other.length() + 1;
    m_chars_ptr = new char[len];
    strcpy(m_chars_ptr, other.m_chars_ptr);
}

3 UCPointer

#ifndef UC_POINTER_H
#define UC_POINTER_H

template <typename T>
class UCPointer {
public:
    UCPointer(T* ptr = 0);
    ~UCPointer();
    UCPointer(const UCPointer<T>& other);

    UCPointer<T>& operator=(const UCPointer<T>& other);
    T* operator->() const;
    T& operator*() const;

private:
    T* m_obj_ptr;

    void increase();
    void decrease();
};

#include "uc_pointer.hpp"

#endif
#include "uc_pointer.h"

template <typename T>
UCPointer<T>::UCPointer(T* ptr) : m_obj_ptr(ptr) {
    increase();
}

template <typename T>
UCPointer<T>::~UCPointer() {
    decrease();
}

template <typename T>
UCPointer<T>::UCPointer(const UCPointer<T>& other) : m_obj_ptr(other.m_obj_ptr) {
    increase();
}

template <typename T>
UCPointer<T>& UCPointer<T>::operator=(const UCPointer<T>& other) {
    if (this == &other) {
        return *this;
    }
    decrease();
    m_obj_ptr = other.m_obj_ptr;
    increase();
    return *this;
}

template <typename T>
T* UCPointer<T>::operator->() const {
    return m_obj_ptr;
}

template <typename T>
T& UCPointer<T>::operator*() const {
    return *m_obj_ptr;
}

template <typename T>
void UCPointer<T>::increase() {
    if (m_obj_ptr) {
        m_obj_ptr -> increase();
    }
}

template <typename T>
void UCPointer<T>::decrease() {
    if (m_obj_ptr) {
        m_obj_ptr -> decrease();
    }
}

4 String

#ifndef STRING_H
#define STRING_H

#include "uc_pointer.h"
#include "string_rep.h"

class String {
public:
    String(const char *);
    ~String();
    String(const String& other);

    String& operator=(const String& other);
    int operator==(const String& other) const;
    String operator+(const String& other) const;

    int length() const;
    const char* getRaw() const;
    int refCount() const;

private:
    UCPointer<StringRep> m_string_rep_ptr;
};

#endif
#include "String.h"

#include <cstring>

String::String(const char *str) : m_string_rep_ptr(0) {
    m_string_rep_ptr = new StringRep(str);
}

String::~String() {}

String::String(const String &other) : m_string_rep_ptr(other.m_string_rep_ptr) {}

String& String::operator=(const String& other) {
    if (this == &other) {
        return *this;
    }
    m_string_rep_ptr = other.m_string_rep_ptr;
    return *this;
}

int String::operator==(const String& other) const {
    return m_string_rep_ptr -> equal(*other.m_string_rep_ptr);
}

String String::operator+(const String& other) const {
    int len = length() + other.length() + 1;
    char* new_str = new char[len];
    strcpy(new_str, m_string_rep_ptr -> get_chars());
    strcat(new_str, other.m_string_rep_ptr -> get_chars());
    String result(new_str);
    delete[] new_str;
    new_str = nullptr;
    return result;
}

int String::length() const {
    return m_string_rep_ptr -> length();
}

const char* String::getRaw() const {
    return m_string_rep_ptr -> get_chars();
}

int String::refCount() const {
    return m_string_rep_ptr -> get_ref_count();
}

评论区

欢迎在评论区指出文档错误,为文档提供宝贵意见,或写下你的疑问