一个完整的C++类应该包含什么?

Posted 心泻

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了一个完整的C++类应该包含什么?相关的知识,希望对你有一定的参考价值。

1. 一个类有:3构造2赋值1析构 函数 + 拷贝移动 操作

2. 构造函数和析构函数的执行顺序:

  • 构造函数:先初始化成员,再执行函数体

  • 析构函数:先执行函数体,再销毁成员(销毁动作即调用成员的析构函数[内置类型无析构,类类型得有析构])

3. 几个法则:

  • 需要析构函数的类通常需要拷贝构造+拷贝赋值

  • 拷贝构造和拷贝赋值成对出现

4. =default显示要求编译器生成合成版本

5. =delete显示要求编译器定义删除该函数(一般来阻止拷贝)、旧标准通过设定为private来阻止拷贝

6. 交换操作:三次拷贝动作。因此在一个类中设计一个swap函数是重要的优化手段。

7. 将赋值函数理解为“=”,将拷贝操作理解为“分配内存副本”。一个赋值拷贝中,包含了拷贝操作和析构函数(防止将自身赋值自己)


一个完整的类示例代码:

class myClass
{
public:
    myClass(const string s = string("")) ://默认构造
        m_s(new string(s)), 
        m_id(0) 
    { 
        cout << "默认构造调用..." << m_s << endl; 
    }
    myClass(const myClass& mc) //拷贝构造
    {
        m_id = mc.m_id;
        if (m_s) delete m_s;
        m_s = new string(*mc.m_s);//分配内存操作(拷贝)
        cout << "拷贝构造调用..." << m_s << endl;
    }
    myClass(myClass&& mc)//移动构造
    {
        m_id = mc.m_id;
        m_s = mc.m_s;
        mc.m_s = nullptr;
        cout << "移动构造调用..." << m_s << endl;
    }

    myClass& operator=(myClass& mc) //拷贝赋值
    {
        m_id = mc.m_id;
        string* temp = new string(*mc.m_s);//分配内存操作(拷贝)
        if (m_s) delete m_s;
        m_s = temp;
        temp = nullptr;
        cout << "拷贝赋值调用..." << m_s << endl;
        return *this;
    }
    myClass& operator=(myClass&& mc)//移动赋值
    {
        if (this != &mc)
        {
            m_id = mc.m_id;
            m_s = mc.m_s;
            mc.m_s = nullptr;
        }
        cout << "移动赋值调用..." << m_s << endl;
        return *this;
    }

    ~myClass()
    {
        if (m_s) 
        {
            delete m_s;
            m_s = nullptr;
        }
        cout << "析构函数调用..." << endl;
    }

private:
    int m_id;
    string* m_s;
};

int main()
{
    myClass A;//默认构造
    myClass B(A);//拷贝构造
    myClass C(std::move(B));//移动构造
    cout << endl;
    C = A;// 拷贝赋值
    C = std::move(A);//移动赋值

    system("pause");
    return 0;
}
执行结果:


以上是关于一个完整的C++类应该包含什么?的主要内容,如果未能解决你的问题,请参考以下文章

C++模板类的继承

如何检查 C++ 类是不是不完整(仅声明)?

表现为局部变量的 C++ 类成员

PATH 是不是应该包含二进制文件的目录或完整路径?

在堆栈上分配不完整的类型

如何在C++中获得完整的类型名称