zoukankan      html  css  js  c++  java
  • C++带指针的类的注意点

    /**
     作者: cwl
     内容:
            带指针类的注意点
            c++构造函数,拷贝构造,拷贝赋值
            new delete解析
    
    */
    #include <bits/stdc++.h>
    
    using namespace std;
    
    class String {
    public:
        String(const char* cstr = 0) {
            if(cstr) {
                m_data = new char[strlen(cstr) + 1];
                strcpy(m_data, cstr);
            } else {
                m_data = new char[1];
                *m_data = '';
            }
        }
    
        ///拷贝构造,接受自己这种东西的引用
        String(const String& str) {
            m_data = new char[strlen(str.m_data) + 1];
            strcpy(m_data, str.m_data);
        }
    
        ///拷贝赋值,接受自己这种东西的引用
        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;
        }
    
        ~String() {
            delete[] m_data;
        }
    
        char* get_c_str() const {
            return m_data;
        }
    private:
        char* m_data;
    };
    
    inline ostream&
    operator << (ostream& os, const String &str) {
        os << str.get_c_str();
        return os;
    }
    
    int main() {
    
        /**
            c++中类四个重要部分
            构造函数
            析构函数
            拷贝构造
            拷贝赋值
        */
    
        ///[1] 如果你的class如果带着指针,就必须重写拷贝构造和拷贝赋值
        /**
            构造和析构是带指针的类必备的,而容易被忽略的是下面两个部分。
    
            【1.1】拷贝构造
    
            String(const String& str) {
                m_data = new char[strlen(str.m_data) + 1];
                strcpy(m_data, str.m_data);
            }
            可能会有疑问,str中的m_data明明是private为什么能直接访问?
            答:解释有很多,其中一个是一个类的不同对象互为友元
    
            【1.2】拷贝赋值
    
            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;
            }
    
            杀掉原来的,创建一个同大小的空间,返回。
            细节是要检测是否是检测自我赋值。
            if(this == &str) {
                return *this;
            }
            多想一步,加强代码稳定性。
    
    
            下面我们添加输出
            inline ostream&
            operator << (ostream& os, const String &str) {
                os << str.get_c_str();
                return os;
            }
        */
        String a = "hello";
        cout << a << endl;
    
        /**
            堆和栈
            【1】String a("qqq");
                    a是栈空间,有操作系统创建在作用域{}结束后释放。
                    自动,auto,也就是旧的时候的auto语义,c++11前的
            【2】String *p = new String("asd");
                    p在栈空间,执行了new处理的堆空间。需要手动delete
                    否则会出现[内存泄漏]
            【3】static int a;
                    声明周期扩展被扩张
            【4】全局对象
                    生命在main之前,main结束后才析构
        */
    
        ///【new】new 会先申请内存,转形,然后调用构造函数
        ///new 的过程
        ///注:operator new是一个函数的名字,c++中能查到源代码
    
        /**
            String *pc;
            void* mem = operator new(sizeof(String));   申请空间
            pc = static_cast<String*>(mem);             类型转化
            pc->String::String("asd");    调用构造函数,直接调会有问题,这里只是示例
    
        */
    
        ///【delete】delete的过程
        /// String::~String(ps)     //析构函数
        /// operator delete(ps)     //释放内存
    
        /**
            new 和 delete 底层使用malloc和delete获得空间
    
        */
    
        return 0;
    }
    
    
  • 相关阅读:
    POJ
    CodeForces
    部分和问题
    NOIP200502校门外的树
    消灭虫子
    抓牛
    最长不下降子序列的长度
    HDNoip201501计算结果最小
    抽签
    Ants
  • 原文地址:https://www.cnblogs.com/Q1143316492/p/10385672.html
Copyright © 2011-2022 走看看