C++11的default和delete关键字

C11的新特性实在是太多了,这2个关键字关注的人倒是少了很多,其中有一个原因便是编译器支持得太慢了(VS到VS2013才支持上),不过这2个关键字那真是极为有用的,下面我们来看看。

【default关键字】
首先我们有一个字符串类:
class CString
{
    char* _str;

public:
    //构造函数
    CString(const char* pstr) : _str(nullptr)
    {
        UpdateString(pstr);
    }

    //析构函数
    ~CString()
    {
        if (_str)
            free(_str);
    }

public:
    void UpdateString(const char* pstr) throw()
    {
        if (pstr == nullptr)
            return;

        if (_str)
            free(_str);

        _str = (char*)malloc(strlen(pstr) + 1);
        strcpy(_str,pstr);
    }

public:
    char* GetStr() const throw()
    {
        return _str;
    }
};
我们可以这样使用:
auto str = std::make_unique<CString>("123");
printf(str->GetStr());
但是这样是不行的:
auto str = std::make_unique<CString>(); //失败,因为没有一个无参构造函数

好,我们用default来:
class CString
{
    char* _str = nullptr;
    
public:
    CString() = default;

public:
    //构造函数
    CString(const char* pstr) : _str(nullptr)
    {
        UpdateString(pstr);
    }

    //析构函数
    ~CString()
    {
        if (_str)
            free(_str);
    }

public:
    void UpdateString(const char* pstr) throw()
    {
        if (pstr == nullptr)
            return;

        if (_str)
            free(_str);

        _str = (char*)malloc(strlen(pstr) + 1);
        strcpy(_str,pstr);
    }

public:
    char* GetStr() const throw()
    {
        return _str;
    }
};

于是我们可以这样使用了:
auto str_def = std::make_unique<CString>();
str_def->UpdateString(“123”);
printf(str_def->GetStr() == nullptr ? "None":str_def->GetStr());

【delete关键字】
假设我们有这样一个类,这个类是用于自动申请内存,进行RAII式管理:
(避免麻烦那些什么拷贝构造拷贝赋值移动构造什么的就不写了)
template<typename T>
class CStackMemoryAlloctor
{
    mutable T* _ptr;

public:
    explicit CStackMemoryAlloctor(size_t size) throw() : _ptr(nullptr)
    {
        _ptr = (T*)malloc(size);
    }

    ~CStackMemoryAlloctor()
    {
        if (_ptr)
            free(_ptr);
    }

public:
    operator T*() const throw()
    {
        T* tmp = _ptr;
        _ptr = nullptr;
        return tmp;
    }

public:
    T* GetPtr() const throw()
    {
        return _ptr;
    }
};

我们这样使用这个类:
CStackMemoryAlloctor<wchar_t> str(128);
wchar_t* pstr = str.GetPtr();
wcscpy(pstr,L"123\n");
wprintf(pstr);

但是别人也可以这样使用:
auto p = std::make_unique<CStackMemoryAlloctor<wchar_t>>(128);

因为这个类依然可以进行默认new,我们不想让人家进行new怎么办,老办法就是这样:
private:
    void* operator new(std::size_t)
    {
        return nullptr;
    }
把new设置为private了,就行了,但是这样如果别人尝试new,那看到的错误提示简直惨不忍睹。。。
于是C11的delete人性化多了:
public:
    void* operator new(std::size_t) = delete;

当尝试new的时候,提示十分友好,这个方法已被删除。
这个delete可以用来删任何你不爽的东西,比如拷贝构造,赋值拷贝什么鸡巴毛的东西。
在C++中,`default`和`delete`关键字具有以下作用: 1. `default`关键字:用于指示编译器生成默认的特殊成员函数的实现。当类声明了特殊成员函数(如默认构造函数、拷贝构造函数、拷贝赋值运算符、析构函数)但没有提供具体的实现时,可以使用`default`关键字告诉编译器生成默认的实现。默认构造函数创建对象时不执行任何操作,拷贝构造函数用于对象的拷贝初始化,拷贝赋值运算符用于对象的赋值操作,析构函数用于对象的销毁。 示例: ```cpp class MyClass { public: // 使用default关键字声明默认构造函数 MyClass() = default; // 使用default关键字声明拷贝构造函数 MyClass(const MyClass& other) = default; // 使用default关键字声明拷贝赋值运算符 MyClass& operator=(const MyClass& other) = default; // 使用default关键字声明析构函数 ~MyClass() = default; }; ``` 2. `delete`关键字:用于禁止编译器生成特殊成员函数或某个特定的重载函数。通过使用`delete`关键字,可以显式删除某个特殊成员函数的默认实现,使其在编译时变为不可用。也可以通过删除某个特定的重载函数,阻止其在特定情况下的使用。 示例: ```cpp class MyClass { public: // 使用delete关键字删除默认构造函数,禁止通过无参构造函数创建对象 MyClass() = delete; // 使用delete关键字删除拷贝赋值运算符,禁止对象的赋值操作 MyClass& operator=(const MyClass& other) = delete; // 删除某个特定的重载函数 void func(int) { ... } void func(double) = delete; // 禁止使用double类型参数的func函数 }; ``` 需要注意的是,`default`和`delete`关键字只能用于特殊成员函数,而不能用于普通成员函数或其他类型的函数。此外,`delete`关键字还可以用于删除特定的重载函数,通过对函数的参数列表进行删除,使得该函数在特定情况下不可用。
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值