简体   繁体   中英

How can I get away from casting in C++?

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.

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.

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)

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

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

Just make percentOfProgress an 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 . 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.

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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