假设我有一个名为AudioSample
的类,实现不相关。
AudioSamples可以从多个源加载,对于每个源,我从AudioSample派生一个类,为相关源添加相关的加载器代码。加载后,我会将对象传递给按值使用AudioSample
的函数。
我似乎很好,它可以防止使用各种加载函数污染基类,并防止在必须添加新加载器时修改(经过测试的)基类。
然而,当搜索stackoverflow进行对象切片时,我只找到将其描述为问题的答案并解释它的潜在缺陷,这让我想知道:我是否以某种方式使用它我不应该这样做?通过这样做,我是否会遇到潜在的问题,我目前还没有意识到这一点?
答案 0 :(得分:6)
对象切片本身并不是问题,因为它是一个非常明确定义的操作。只是它通常会提出一个“WTF”时刻,因为它很少有意。我对代码质量的偏好度量是每分钟读数的WTF的倒数,所以从这个角度来看,这是一个坏主意,因为它需要大量的文档才能说“是的,我真的知道我在做什么。”
因此,我更倾向于将它限制在一个名副其实且功能齐全的功能上。像这样:
class AudioSampleLoadedViaFoo : public AudioSample
{
// ...
public:
AudioSample getLoadedSample() const
{
return *this; // Slice on purpose to remove load-specific stuff
}
};
这样,在外部代码中使用只会看到定义明确的函数,切片只是一个实现细节。
答案 1 :(得分:3)
对于每个源我从AudioSample派生一个类,为相关源添加相关的加载器代码
实际上听起来像#34;加载程序代码"不应该在那里开始,或者你应该超载你的construtor /使它更一般,或者你需要一个工厂或商店"加载器代码"在std::function
。
虽然定义了切片,但这并不常见,我只担心其他开发人员在第一眼就不会理解那段代码,这表明(通常)代码不好。为什么不从头开始写一个好的可读代码?
为了分享外部开发人员的奇怪之处,您是否还会为每个返回字符串的函数派生并切片std::string
?
答案 2 :(得分:0)
您如何知道要调用哪个加载程序代码?如果对象被切片,那么被切掉的东西之一就是多态行为 - 一切都像基类的实例。并且因为它很容易防止(通过引用或指针传递,这在任何情况下可能在制作副本方面更有效),很难理解为什么你会想要这样做