什么是使用=delete的一些场景?

12

今天早些时候,我提出了一个问题,链接地址为这里。这个问题引发了另外一个问题:什么时候应该使用=delete?我认为在SO网站上没有专门介绍=delete的文章,因此我查阅了一本名为“C++程序设计语言”的书籍,并将我的研究结果列在下面的答案中。

如果还有其他需要补充的内容或者我理解有误,请评论或回答。


@Rapptz 我看到了那篇文章,但我认为它是关于 =default=delete作用。这篇文章是关于 =delete的实际用途。很容易理解 =delete禁止使用该函数,但你为什么要这样做呢?这篇文章回答了为什么。 - Oleksiy
“这个问题已经有了一个答案…” - 呃,不是的。尽管这些问题相关,但它们并不是重复的。 - Oleksiy
1个回答

30

原来=delete非常有用!以下是几个例子:


基本上我们可以通过这种方式防止复制基类,因为它经常会导致切片问题:

struct Base {

    Base(){}

    Base& operator=(const Base&) = delete; // disallow copying
    Base(const Base&) = delete;

    Base& operator=(Base && ) = delete;      // disallow moving
    Base(Base && ) = delete;

};

struct Der : public Base {};

void func() {

    Der d;
    Base base = d; // this won't work because the copy constructor is deleted!
                   // this behavior is desired - otherwise slicing would occur

}

当模板函数无法使用某种类型时,这个时候也是很有用的:

template<class T>
void fn(T p) { /* ... */ }; // do something with T

void fn(int) = delete; // disallow use with int

void fun() {

    fn(4);      // aha! cannot use fn() with int!
    fn(-4.5);   // fine
    fn("hello");// fine
}

=delete 可以防止非预期的类型转换:

struct Z {

    Z(double); // can initialize with a double
    Z(int) = delete; // but not with an integer

};

void f() {

    Z z1 { 1 }; // error! can't use int
    Z z2 { 1.0 }; // double is ok

}

一些更高级的使用方式包括禁止堆栈或自由存储器分配:
class FS_Only {
    ~FS_Only() = delete;  // disallow stack allocation
};

class Stack_Only {
    void* operator new(size_t) = delete;   // disallow heap allocation
};

我希望这篇文章能对某些人有所帮助!=delete可以帮助编写易读、无bug和优雅的代码。


编辑:

正如评论中正确指出的那样,现在不可能删除FS_Only对象,因此这并不是一个很好的使用=delete的例子。


1
哇,我知道的唯一用途就是禁止复制。我没想到还有这么多其他用途。 - Siyuan Ren
4
当你使用delete删除堆上分配的对象时,也会调用析构函数。因此,通过将析构函数标记为已删除,您可以创建一个类,可以用于在堆上分配内存,但永远不会被删除。 - Some programmer dude
1
哇,随着C++规范的每一次新修订,它变得越来越不像一种语言了。这听起来很有用,但对于像我这样的恐龙来说,语法实在是太丑陋了。 - Andon M. Coleman
我同意Andon的观点,=delete语法本应该是一种“注释”,但它却与其他语法产生了冲突。 - rano
4
@AndonM.Coleman 我真的不知道为什么它被认为是复杂的(是因为关键字的重复使用吗?如果是这样,上下文线索会有所帮助)。在我看来,C++语法非常清晰。我相当确定来自C的函数指针等更复杂的语法还有很多。 - Rapptz
显示剩余13条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接