把虚拟方法放在可复制类型上是个好主意吗?

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (2)
  • 关注 (0)
  • 查看 (24)

我将类视为适合于几个主要类别的类,假设这四个类是简单的:

  • 价值类有一些数据和一堆操作。它们可以被复制并有意义地进行比较,以实现平等(预期副本将通过==)这些几乎总是缺乏虚拟方法。
  • 独特类其实例具有禁用分配和复制的标识。通常没有operator==因为您将它们作为指针进行比较,而不是作为对象进行比较。这些通常有很多虚拟方法,因为没有风险目标切片因为你被迫通过指针或引用传递它们。
  • 独特但可复制的类它禁止复制,但预先设计支持克隆,如果这是你真正想要的。
  • 容器类继承了他们所持有的一切财产,它们往往没有虚拟方法.

不管持有这种非正式的信仰系统,我曾经尝试过在一些可复制的东西上添加一个虚拟方法。虽然我可能认为“如果这样做真的很酷”,但它不可避免地会破裂。

提问于
用户回答回答于

复制多态类没有本质上的错误。问题是能否复制一个非叶类。对象切片会让你。

一个好的经验法则是不要从具体的类派生...。这样,非叶类自动不可实例化,因此不可复制.。不过,为了安全起见,禁用他们的任务也不会有什么害处。

当然,通过虚拟函数复制对象没有什么问题。这种复制是安全的。

多态类通常不是“值类”,但它确实发生了。std::stringstream我想到了。它是不可复制的,但它是可移动的(在C++11中),移动和复制在切片方面没有什么不同.

用户回答回答于

我所拥有的唯一反例是类,这些类应该是堆栈分配的,而不是堆分配的。我使用它的一个方案是依赖注入:

class LoggerInterface { public: virtual void log() = 0; };

class FileLogger final: public LoggerInterface { ... };

int main() {
    FileLogger logger("log.txt");

    callMethod(logger, ...);
}

这里的关键是final关键字,这意味着复制FileLogger不能导致对象切片。

然而,可能只是因为final翻身FileLogger变成一个值类。

扫码关注云+社区