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

时间:2022-09-06 08:33:54

In C++ you can cast a couple ways, C-style casting or C++ casts. Bjarne Stroustrup and a host of other C++ experts say that a good design should have no casting.

在C ++中,你可以使用几种方式,C风格的转换或C ++转换。 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。

5 个解决方案

#1


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. I'm not sure it's completely determined which way a cast to int will round. (ie towards +inf, towards -inf, or towards zero)

另外,对于像这样的算术运算,你可能想要更加小心。你应该在施放到int之前应用ceil或floor。我不确定它是否完全决定了转换为int的方式。 (即朝+ inf,朝-inf或朝零)

#2


I don't think the cast is necessary, there is an implicit cast from double to int. Comeau compiles this:

我不认为演员是必要的,有一个从double到int的隐式转换。 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.

没有错误。期望这种交叉数字转换,这就是为什么它们之间存在隐式转换。

#3


You don't need to cast, doubles are casted automatically to int, if needed. You should add 0.5 to the dProgress value when setting position in order for it to be properly rounded. When casting double to int, the decimal places are truncated and not rounded.

如果需要,您不需要强制转换,双精度自动转换为int。设置位置时,应将dProgress值加0.5,以使其正确舍入。将double转换为int时,小数位被截断而不是舍入。

#4


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 );
}

#5


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. 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.

当人们说要避免强制转换时,它们通常意味着用户定义的类型之间。例如,您不应该经常需要从基类转发到派生类。如果您需要,您应该仔细查看您的类层次结构,看看它有什么问题。 reinterpret_cast也是如此。如果你经常使用它,在不相关的指针类型之间进行转换,这可能表明你正在做一些C风格的低级别bit-hackery,这可以而且应该避免。

Casting between int and float, or other numeric types, is pretty much to be expected.

在int和float之间或其他数字类型之间进行转换是非常值得期待的。

#1


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. I'm not sure it's completely determined which way a cast to int will round. (ie towards +inf, towards -inf, or towards zero)

另外,对于像这样的算术运算,你可能想要更加小心。你应该在施放到int之前应用ceil或floor。我不确定它是否完全决定了转换为int的方式。 (即朝+ inf,朝-inf或朝零)

#2


I don't think the cast is necessary, there is an implicit cast from double to int. Comeau compiles this:

我不认为演员是必要的,有一个从double到int的隐式转换。 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.

没有错误。期望这种交叉数字转换,这就是为什么它们之间存在隐式转换。

#3


You don't need to cast, doubles are casted automatically to int, if needed. You should add 0.5 to the dProgress value when setting position in order for it to be properly rounded. When casting double to int, the decimal places are truncated and not rounded.

如果需要,您不需要强制转换,双精度自动转换为int。设置位置时,应将dProgress值加0.5,以使其正确舍入。将double转换为int时,小数位被截断而不是舍入。

#4


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 );
}

#5


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. 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.

当人们说要避免强制转换时,它们通常意味着用户定义的类型之间。例如,您不应该经常需要从基类转发到派生类。如果您需要,您应该仔细查看您的类层次结构,看看它有什么问题。 reinterpret_cast也是如此。如果你经常使用它,在不相关的指针类型之间进行转换,这可能表明你正在做一些C风格的低级别bit-hackery,这可以而且应该避免。

Casting between int and float, or other numeric types, is pretty much to be expected.

在int和float之间或其他数字类型之间进行转换是非常值得期待的。