想象一下,在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
?
如果可能的话,两者都没有。设计你的类,使基类定义一个完全有用的接口,并且只使用基类指针。
然而,有时您会被遗留代码所困扰,在这种情况下,我会明确指出您正在将其强制转换为const。
编辑:我应该明确指出,偶尔会出现非多态性情况,使用强制转换的解决方案是合适的。一般来说,降级可能是一种设计上的味道,但它并不总是表明某些地方肯定出了问题。
我努力尽可能少地进行显式强制转换,如果可能的话,其他一切都是隐式的。
所以我会使用前者(即不在演员阵容中包括const
)。
但这只是我的看法。你也可以在那里写const
,因为它符合你的口味。
好吧,要明确的是,他们也做同样的事情。
现在,如果从const base *
转换为const derived *
,则只有后者有效,而前者也需要const_cast
。如果您从base *
转换为derived *
,则只有前者有效,因为否则您需要丢弃您的演员阵容刚刚添加的const
。
我倾向于避免在强制转换中使用const
修饰符,除非明确需要。换句话说,保持代码尽可能简单。
当然,如果b
可以是另一个派生类的实例,那么在这种情况下应该使用dynamic_cast<>
而不是static_cast<>
。
只要一行代码,我就不会太担心了。如果将来确实将b
更改为const base*
,那么编译器将准确地告诉您哪一行有问题,以及要更改什么。因此,无论哪种方式的好处都是非常小的——其中一种方式缩短了行,另一种可能会在将来当你已经在同一个函数中更改代码时为你节省几秒钟的工作。如果我想这样做的话,我会放入const
,因为它稍微减少了一行代码对另一行代码细节的依赖。但是,如果代码已经写好,我不会特意更改它。
如果你正在设计一个API,那么你应该把const
放在你能放的地方,因为改变API可能很痛苦。我不认为这种潜在的未来变化是痛苦的。