{C++系列} C++基础 day06 拷贝构造和拷贝赋值,静态成员,单例模式
in C/C++ with 0 comment

{C++系列} C++基础 day06 拷贝构造和拷贝赋值,静态成员,单例模式

in C/C++ with 0 comment

#复习:

1 初始化表

类名(形参表):成员变量(初值),...{函数体}

-->以有参的方式初始化成员子对象
-->const/引用

2 this指针

--》区分作用域
--》返回自引用
--》对象自销毁

3 常函数

void func(...)const{...}
常函数中的this指针是常指针,不能通过它直接修改成员变量。
但是被mutable关键字修饰的成员变量可以修改.
常对象只能调用常函数
函数名和形参表相同成员函数,常版本和非 常版本可以构成重载,常对象调常版本,非 常对象调用非常版本。

4 析构函数

~类名(void){清理对象的动态资源}
对象销毁时自动被调用
#对象创建
--》分配内存
--》构造成员子对象
--》执行构造函数代码
#对象销毁
--》执行析构函数代码
--》析构成员子对象
--》释放内存

=======================

十七# 拷贝构造和拷贝赋值

1 浅拷贝和深拷贝


2 当实现两个对象赋值操作时,编译器会将其翻译成“operator=”的函数调用形式,通过它完成两个对象复制,但是类中提供的缺省的拷贝赋值函数是浅拷贝,只是赋值了指针的本身,有double free和内存泄露的问题。所以需要自己定义一个支持深拷贝的“operator=”函数//参考copy2.jpg

类名& operator=(const 类名& that){
    if(&that != this){//防止自赋值
        //释放旧内存
        //分配新内存
        //复制新数据
    }    
    return *this;//返回自引用
}

#举例

深拷贝和浅拷贝,拷贝赋值

#include <iostream>
using namespace std;

class Integer{
public:
    Integer(int data = 0):m_data(new int(data)){
        //m_data = new int(data);
    }
    ~Integer(void){
        delete m_data;
        m_data = NULL;
        cout << "析构函数" << endl;
    }
    //缺省的拷贝构造函数(浅拷贝)
    //Integer i2(i);
    //i2.m_data = i.m_data;
    /*Integer(const Integer& that)
        :m_data(that.m_data){
        //m_data = that.m_data;
    }*/
    //自定义深拷贝
    //Integer i2(i);
    //i2.m_data = new int;
    //*i2.m_data = *i.m_data;
    Integer(const Integer& that)
        :m_data(new int(*that.m_data)){
        //m_data = new int(*that.m_data);
    }
    /*缺省拷贝赋值操作符函数:浅拷贝*/
    //i3 = i2;-->i3.operator=(i2)
    //赋值表达式返回结果应该就是左操作数自身
    /*Integer& operator=(const Integer& that){
        m_data = that.m_data;
        return *this;
    }*/
    //自定义深拷贝赋值:复制指针所指向数据
    //i3 = i2: i3.operator=(i2);
    //this指向i3
    //that对应i2
    Integer& operator=(const Integer& that){
        if(&that != this){//防止自赋值
            delete m_data;//释放旧内存
            //m_data = new int;//分配新内存
            //*m_data = *that.m_data;//拷贝新数据
            m_data = new int(*that.m_data);
        }
        return *this;//返回自引用
    }
    void print(void){
        cout << *m_data << endl;
    }
private:
    int* m_data;
};
int main(void)
{
    Integer i(100);
    i.print();
    Integer i2(i);//拷贝构造
    i2.print();//100
    Integer i3;
    //i3.operator=(i2);
    i3 = i2;//拷贝赋值
    i3.print();//100

    return 0;
}

实现string类型

//笔试题:实现String类型
#include <iostream>
#include <cstring>
using namespace std;
class String{
public:
    //构造函数
    String(const char* str = "")
        :m_str(strcpy(
            new char[strlen(str)+1],str)){}
    //析构函数
    ~String(void){
        delete[] m_str;
        m_str = NULL;
    }
    //拷贝构造函数(深拷贝)
    String(const String& that)
        :m_str(
            strcpy(new char[strlen(that.m_str)+1],
            that.m_str)){}
    //拷贝赋值函数(深拷贝)
    //s2 = s3;-->s2.operator=(s3)
    String& operator=(const String& that){
        if(&that !=  this){
            delete[] m_str;
            m_str = new char[strlen(that.m_str)+1];
            strcpy(m_str,that.m_str);
            /*char* str = 
                new char[strlen(that.m_str)+1];
            delete[] m_str;
            m_str = strcpy(str,that.m_str);*/

            /*String temp(that);
            swap(m_str,temp.m_str);*/
        }
        return *this;
    }
    const char* c_str(void)const{
        return m_str;
    }
private:
    char* m_str;
};
int main(void)
{
    //String s1 = "hello world!";
    //String s1 = String("hello world!");
    String s1("hello world!");
    cout << s1.c_str() << endl;
    
    String s2(s1);//拷贝构造
    cout << s2.c_str() << endl;//hello world!
    
    String s3("hello C++!");
    s2 = s3;//拷贝赋值
    cout << s2.c_str() << endl;//hello C++!

    return 0;
}

十八# 静态成员(static)

1 #静态成员变量

  class 类名{
          static 数据类型 变量名;//声明
  };

数据类型 类名::变量名=初值;//定义和初始化

对象名.静态成员变量;
对象指针->静态成员变量;

#举例

静态成员变量举例

#include <iostream>
using namespace std;

class A{
public:
    A(int data = 0):m_data(data){}
    int m_data;
    static int s_data;//声明
};
int A::s_data = 200;//定义和初始化
int main(void)
{
    A a(100);
    cout << "size=" << sizeof(a) << endl;//4
    cout << a.m_data << endl;
    cout << a.s_data << endl;
    cout << A::s_data << endl;//推荐
    A a2;
    //静态成员变量虽然不属于对象,但是可以被所
    //有对象共享,都可以使用,如果一个对象修改
    //了静态成员的值,其它对象再访问也会改变。
    a2.s_data = 123;
    cout << a.s_data << endl;//123
    return 0;
}

2# 静态成员函数

class 类名{
    static 返回类型 函数名(形参表){..}
};

1)静态成员函数没有this指针,也没有const属性
2)访问:
类名::静态成员函数(实参);//推荐
对象名.静态成员函数(实参);
对象指针->静态成员函数(实参);

注:在静态成员函数中只能访问静态成员。

#举例

静态成员函数举例

#include <iostream>
using namespace std;

class A{
public:
    A(int data = 0):m_data(data){}
    static void func1(void){
        cout << "静态成员函数" << endl;
        //cout << m_data << endl;
        cout << s_data << endl;
    }
    void func2(void){
        cout << "非 静态成员函数" << endl;
        cout << m_data << endl;
        cout << s_data << endl;
    }
    int m_data;
    static int s_data;//声明
};
int A::s_data = 200;//定义和初始化
int main(void)
{
    A a(100);
    a.func2();
    A::func1();
    return 0;
}

3# 单例模式

定义:一个类只允许创建唯一的对象。

饿汉式:单例对象无论用或不用,程序启动即创建
懒汉式:单例对象在用时创建,不用即销毁

#举例

恶汉式单例模式举例

#include <iostream>
using namespace std;

class A{
public:
    A(int data = 0):m_data(data){}
    static void func1(void){
        cout << "静态成员函数" << endl;
        //cout << m_data << endl;
        cout << s_data << endl;
    }
    void func2(void){
        cout << "非 静态成员函数" << endl;
        cout << m_data << endl;
        cout << s_data << endl;
    }
    int m_data;
    static int s_data;//声明
};
int A::s_data = 200;//定义和初始化
int main(void)
{
    A a(100);
    a.func2();
    A::func1();
    return 0;
}

懒汉式单例模式举例

//单例模式:懒汉式
#include <iostream>
using namespace std;

class A{
public:
    //3)提供访问接口
    static A& getInstance(void){
        if(s_instance == NULL){
            s_instance = new A(1234);
        }
        ++s_count;
        return *s_instance;
    }
    //单例对象可能有多个人都在使用
    //应该是最后一个人调用release才去delete
    void release(void){
        if(--s_count == 0){
            delete s_instance;
            s_instance = NULL;
        }
    }
    void print(void){
        cout << m_data << endl;
    }
private:
    //1)私有化构造函数
    A(int data = 0):m_data(data){}
    A(const A&);//声明拷贝构造为私有
    int m_data;
    //2)维护唯一的对象
    static A* s_instance;

    //记录使用单例对象的人数
    static int s_count;
};
A* A::s_instance = NULL;
int A::s_count = 0;

int main(void)
{
//    A a(100);//error
//    A* pa = new A(100);//error
    A& a1 = A::getInstance();
    A& a2 = A::getInstance();
    a1.print();
    cout << "&a1=" << &a1 << endl;
    cout << "&a2=" << &a2 << endl;
    a1.release();
    a2.print();
    a2.release();
    return 0;
}
Responses