2

想象在 C++ 中有两个类,一个命名derived,另一个命名base为第一个的基类。如果我有以下代码,这是首选:

base *b = init_value_here;
const derived *d = static_cast<derived *>(b);

或者

base *b = init_value_here;
const derived *d = static_cast<const derived *>(b);

换句话说,const由于编译器可以提升为常量,因此在不需要时排除在静态强制转换中是否更好,或者最好将其包括在内以放宽对它的限制,b以便const将来更容易制作?

4

4 回答 4

8

如果可能,一个都没有。设计您的类,以便基类定义一个完全有用的接口并仅使用基类指针。

但是,有时您会遇到遗留代码,在这种情况下,我会明确说明您将其转换为 const。

编辑:我应该明确指出,偶尔会出现非多态情况,使用强制转换的解决方案是合适的。一般来说,向下转换可能是一种设计气味,但并不总是表明某些事情肯定是错误的。

于 2011-06-17T18:08:35.417 回答
3

好吧,要清楚,他们做同样的事情。

现在,如果您从 a 转换const base *为 a const derived *,则只有后者是有效的,而前者也需要 a const_cast。如果您从 a 转换base *为 a derived *,则只有前者是有效的,否则您需要抛弃const您的演员刚刚添加的 -ness。

我的偏好是避免const在强制转换中使用修饰符,除非明确需要。换句话说,让代码尽可能简单,只要编译器允许。

当然,您应该使用dynamic_cast<>而不是static_cast<>在这种情况下,如果b可能是另一个派生类的实例。

于 2011-06-17T18:10:18.083 回答
3

对于一行代码,我不会太担心。如果您将来确实更改bconst base*,那么编译器将准确告诉您哪一行有问题以及要更改的内容。因此,无论哪种方式,好处都是微乎其微的——其中一个使线路更短,另一个可能会在您已经在同一个函数中更改代码的情况下为您节省几秒钟的工作时间。如果我想到const这样做,我会加入,因为它稍微减少了一行代码对另一行细节的依赖。但是如果代码已经写好了,我不会特意去改变它。

如果您正在设计一个 API,那么您应该尽可能地放置const,因为更改 API 可能会很痛苦。我不认为这种潜在的未来变化是痛苦的。

于 2011-06-17T18:19:05.907 回答
3

如果可能的话,我力求尽可能少地进行显式转换,以及其他所有隐式转换。

所以我会使用前者(即不包括const在演员表中)。

但这只是我的意见。你可能也有意见写在const那里,因为它符合你的口味。

于 2011-06-17T18:25:58.143 回答