防止切片的惯用方式? [英] Idiomatic way to prevent slicing?

查看:127
本文介绍了防止切片的惯用方式?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有时,C ++默认允许切片可能会很烦人.例如

Sometimes it can be an annoyance that c++ defaults to allow slicing. For example

struct foo { int a; };
struct bar : foo { int b; };

int main() {
    bar x{1,2};
    foo y = x; // <- I dont want this to compile!
}

编译并按预期运行!但是,如果我不想启用切片怎么办?

This compiles and runs as expected! Though, what if I dont want to enable slicing?

什么是写foo以便不能对任何派生类的实例进行切片的惯用方式?

What is the idiomatic way to write foo such that one cannot slice instances of any derived class?

推荐答案

我不确定是否有命名习语,但是您可以向重载集中添加一个删除的函数,该函数比基类更匹配切片操作.如果将foo更改为

I'm not sure if there is a named idiom for it but you can add a deleted function to the overload set that is a better match then the base classes slicing operations. If you change foo to

struct foo 
{ 
    int a; 
    foo() = default; // you have to add this because of the template constructor

    template<typename T>
    foo(const T&) = delete; // error trying to copy anything but a foo

    template<typename T>
    foo& operator=(const T&) = delete; // error assigning anything else but a foo
};

然后,您只能复制构造或将foo分配给foo.任何其他类型都会选择功能模板,并且会出现有关使用已删除功能的错误信息.这确实意味着您的类以及使用它的类不再可以聚合.由于添加的成员是模板,因此它们不被视为复制构造函数或复制分配运算符,因此您将获得默认的复制并移动构造函数和分配运算符.

then you can only ever copy construct or copy assign a foo to foo. Any other type will pick the function template and you'll get an error about using a deleted function. This does mean that your class, and the classes that use it can no longer be an aggregate though. Since the members that are added are templates, they are not considered copy constructors or copy assignment operators so you'll get the default copy and move constructors and assignment operators.

这篇关于防止切片的惯用方式?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆