简体   繁体   English

如何摆脱C ++中的强制转换?

[英]How can I get away from casting in C++?

In C++ you can cast a couple ways, C-style casting or C++ casts. 在C ++中,你可以使用几种方式,C风格的转换或C ++转换。 Bjarne Stroustrup and a host of other C++ experts say that a good design should have no casting. Bjarne Stroustrup和许多其他C ++专家说,一个好的设计应该没有铸造。

Can you help me out here with redesigning the code below to get rid of the cast? 你可以帮我在这里重新设计下面的代码来摆脱演员阵容吗?

void CProgressBar::SetPosition( int nPos );  //unable to change

void CSaveDialog::UpdatePosition( double dProgress )
{
   double percentOfProgress = dProgress * 100;
   m_pProgressBar->SetPosition( static_cast<int>( percentOfProgress ) );
}

I can modify UpdatePosition, but not SetPosition. 我可以修改UpdatePosition,但不能修改SetPosition。

I think casting in arithmetic can be OK. 我认为在算术中投射可以。 The type of casting that should really be avoided is up and down (or across) your own class hierarchy. 应该真正避免的转换类型是在您自己的类层次结构中上下(或跨越)。

Also, for casting in arithmetic like this you probably want to be more careful. 另外,对于像这样的算术运算,你可能想要更加小心。 You should probably apply ceil or floor before casting to an int . 你应该在施放到int之前应用ceilfloor I'm not sure it's completely determined which way a cast to int will round. 我不确定它是否完全决定了转换为int的方式。 (ie towards +inf, towards -inf, or towards zero) (即朝+ inf,朝-inf或朝零)

I don't think the cast is necessary, there is an implicit cast from double to int. 我不认为演员是必要的,有一个从double到int的隐式转换。 Comeau compiles this: Comeau汇编了这个:

struct CProgressBar {
  void SetPosition( int nPos );  //unable to change
};

struct CSaveDialog {
  void UpdatePosition( double dProgress )
  {
     m_pProgressBar->SetPosition( dProgress * 100  );
  }

  CProgressBar* m_pProgressBar;
};

Without errors. 没有错误。 These kind of cross numeric casts are expected, and that is why there are implicit casts between them. 期望这种交叉数字转换,这就是为什么它们之间存在隐式转换。

You don't need to cast, doubles are casted automatically to int, if needed. 如果需要,您不需要强制转换,双精度自动转换为int。 You should add 0.5 to the dProgress value when setting position in order for it to be properly rounded. 设置位置时,应将dProgress值加0.5,以使其正确舍入。 When casting double to int, the decimal places are truncated and not rounded. 将double转换为int时,小数位被截断而不是舍入。

Just make percentOfProgress an int. 只需将percentOfProgress设为int。

void CProgressBar::SetPosition( int nPos );  //unable to change

void CSaveDialog::UpdatePosition( double dProgress )
{
   int percentOfProgress = dProgress * 100;
   m_pProgressBar->SetPosition( percentOfProgress );
}

When people say to avoid casts, they usually mean between user-defined types. 当人们说要避免强制转换时,它们通常意味着用户定义的类型之间。 You shouldn't, for example, need to downcast from a base class to the derived one very often. 例如,您不应该经常需要从基类转发到派生类。 If you need that, you should probably take a close look at your class hierarchy and see what's wrong with it. 如果您需要,您应该仔细查看您的类层次结构,看看它有什么问题。 The same goes for reinterpret_cast . reinterpret_cast If you use that often, to cast between unrelated pointer types, it's probably a sign that you're doing some C-style low-level bit-hackery, which could and should be avoided. 如果你经常使用它,在不相关的指针类型之间进行转换,这可能表明你正在做一些C风格的低级别bit-hackery,这可以而且应该避免。

Casting between int and float, or other numeric types, is pretty much to be expected. 在int和float之间或其他数字类型之间进行转换是非常值得期待的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM