c++ - 传递继承引用类型时切片或不切片

标签 c++ pass-by-reference pass-by-value object-slicing

我正在编写一些涉及“现实生活”而不是纯程序实体的代码。假设这是一个处理 Camel 的库。现在,我的图书馆有两只 Camel reference-type类:Camel 和 SingingCamel。 Camel 是一个没有虚拟成员的具体类; SingingCamel : public Camel { } 是一头可以唱歌的 Camel ,并且在编程方面没有覆盖/遮蔽。将唱歌的 Camel 当作不唱歌的 Camel 对待是没有问题的。

现在,由于这些都是引用类型而不是值类型类,所以我宁愿按值传递它们。不幸的是,如果我写:

void have_joyride(Camel camel, Person person)

(记住 - 这些是引用类;这不会创建新的 Camel 或新的人)

...然后我正在切片我的 SingingCamel

C++ 核心指南 say :

ES.63: Don't slice

Slicing -- that is, copying only part of an object using assignment or initialization -- most often leads to errors because the object was meant to be considered as a whole. In the rare cases where the slicing was deliberate the code can be surprising.

现在,我并不是无法避免切片。我当然可以写:

void have_joyride(Camel const &  camel, Person const &  person);

这样就可以了。 ...除了在这种情况下,我实际上需要有四个函数:

void have_joyride(Camel const &  camel, Person const &  person);
void have_joyride(Camel const &  camel, Person       && person);
void have_joyride(Camel       && camel, Person const &  person);
void have_joyride(Camel       && camel, Person       && person);

这违反了another C++ 核心指南:

ES.3: Don't repeat yourself, avoid redundant code

Duplicated or otherwise redundant code obscures intent, makes it harder to understand the logic, and makes maintenance harder, among other problems. It often arises from cut-and-paste programming.

以及this one :

F.16: For "in" parameters, pass cheaply-copied types by value and others by reference to const

Both let the caller know that a function will not modify the argument, and both allow initialization by rvalues.


所以我问自己:

切片,还是不切片,这是一个问题:
受苦是否更高尚
令人发指的重载的 lrefs 和 rrefs,
或者从继承引用对象中获取值,
然后通过,将它们切片。

注释:

最佳答案

这就是C++核心指南say你可以这样做:

Alternative

If you mean to slice, define an explicit operation to do so. This saves readers from confusion.

并调整他们的示例,我会得到:

class SingingCamel : public Camel {
    public:
    Camel as_camel();
    // ...
};

SingingCamel sc { /* ... */ };
Camel c1 {sc};  // ideally prevented by the definition of Camel
Camel c2 {sc.as_camel()};

但坦率地说,我不太喜欢这个解决方案。我想将我的 SingingCamel 传递给采用 Camel 的函数,天真且直接的方式。

关于c++ - 传递继承引用类型时切片或不切片,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/70395077/

相关文章:

c++ - 使用一个 ifstream 变量读取多个文件

c++ - 通过引用传递指针

java - Java是“按引用传递”还是“按值传递”?

java - 可以使用java中的包装类交换两个数字而不创建任何其他类吗?

c++ - RenderWindow不断更新display()导致闪烁

c++ - 使用 MXE 在 Linux for Windows 上交叉编译 - GSL 链接?

c++ - 此代码对于重载比较运算符是否正确?

c++ - 将 vector 的 vector 传递给函数

c++ - 函数调用中的堆栈分配

c++ - 为什么命令行参数的字符串比较不起作用?