【C++语法实践】06-C++ new关键字以及相关重载

C++中new 关键字有三个作用:

1. new operator = operator new + 构造函数 = 分配空间,调用构造函数

2. operator new = 分配空间

3. placement new = 不分配空间,调用构造函数

三种用法简单实例

#include <iostream>
#include <cassert>

using namespace std;

class Tmp
{
public:
    Tmp(int n) : n_(n)
    {
        cout << "Tmp construction" << endl;
    }
    int n_;
};

int main()
{
    Tmp* t1 = new Tmp(100); // new operator = operator new + 构造函数
    cout << t1->n_ << endl;

    char chunk[10];
    Tmp* t2 = new (chunk) Tmp(200); // 在chunk空间中,创建Tmp对象
    // placement new 就地创建对象,不分配内存
    cout << t2->n_ << endl;

    assert((char*)chunk == (char*)t2); // 断言地址是否相等

    // Tmp* t3 = (Tmp*)chunk;
    Tmp* t3 = reinterpret_cast<Tmp*>(chunk); // reinterpret_cast 重新解释的转换
    cout << t3->n_ << endl;
    return 0;
}

operator new 和 placement new相关重载

#include <iostream>
#include <cassert>

using namespace std;

class Tmp
{
public:
    Tmp(int n) : n_(n)
    {
        cout << "Tmp construction" << endl;
    }
    ~Tmp()
    {
        cout << "~Tmp" << endl;
    }

    // 重载 operator new 操作
    void* operator new(size_t size)
    {
        cout << "void* operator new(size_t size)" << endl;
        void* p = malloc(size);
        return p;
    }

    // 与operator new 相匹配的函数
    void operator delete(void* p)
    {
        cout << "void operator delete(void* p)" << endl;
        free(p);
    }

    // 与operator new 相匹配的函数 优先级低于void operator delete(void* p),但是可以共存
    void operator delete(void* p, size_t size)
    {
        cout << "void operator delete(void* p, size_t size)" << endl;
        free(p);
    }

    // 打印文件和行信息
    void* operator new(size_t size, const char* file, long line)
    {
        cout << file << ":" << line;
        void* p = malloc(size);
        return p;
    }

    // 打印文件和行信息,与之相匹配的delete函数
    void operator delete(void* p, const char* file, long line)
    {
        cout << file << ":" << line;
        free(p);
    }

    // placement new,不分配内存
    void* operator new(size_t size, void* p)
    {
        cout << "void* operator new(size_t size, void* p)" << endl;
        return p;
    }

    // placement new 相匹配的delete
    void operator delete(void* , void*)
    {
        cout << "void operator delete(void* , void*)" << endl;
    }

    int n_;
};

// 全局 operator new, 如 char* str = new char;
void* operator new(size_t size)
{
    cout << "global void* operator new(size_t size)" << endl;
    void* p = malloc(size);
    return p;
}

// 与全局operator new相匹配
void operator delete(void* p)
{
    cout << "void operator delete(void* p)" << endl;
    free(p);
}

// 全局 operator new, 如 char* str = new char;
void* operator new[](size_t size)
{
    cout << "global void* operator new[](size_t size)" << endl;
    void* p = malloc(size);
    return p;
}

// 与全局operator new相匹配
void operator delete[](void* p)
{
    cout << "void operator delete[](void* p)" << endl;
    free(p);
}

int main()
{
    Tmp* t1 = new Tmp(100); // new operator = operator new + 构造函数
    cout << t1->n_ << endl;
    delete t1;

    char* str = new char[10]; // 全局operator new
    delete[] str;

    char chunk[10];
    Tmp* t2 = new (chunk) Tmp(200); // 在chunk空间中,创建Tmp对象,placement new 就地创建对象,不分配内存

    t2->~Tmp(); // placement new中调用了构造函数,那么就应该调用析构函数,但是t2并不是在堆上分配的内存
                // 不应该用delete, 所以应该显示调用析构函数



    assert((char*)chunk == (char*)t2);
    // Tmp* t3 = (Tmp*)chunk;
    Tmp* t3 = reinterpret_cast<Tmp*>(chunk); // reinterpret_cast 重新解释的转换
    cout << t3->n_ << endl;


    Tmp* t4 = new(__FILE__, __LINE__) Tmp(400);
    delete t4;

    return 0;
}

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注

开始在上面输入您的搜索词,然后按回车进行搜索。按ESC取消。

返回顶部