简体   繁体   中英

C++ Passing pointers / Constants. Efficiency

I am working on a project with a friend that does a lot of computation and we are using c++ for it. I havent used c++ in a while and he is suggesting some fixes. I hoped I could come here for a more in depth explanation and maybe could be linked to some more articles.

He says its more efficient instead of having this

Hand::Hand(Card one, Card two)

To have this

Hand::Hand(const Card &one, const Card &two)

Is this correct? What about passing a constant address rather than the object itself makes it more efficient? He mentioned passing a reference instead of making a copy. If I dont pass by address, will it construct a new card object as a copy of the one I've passed?

Also

Instead of

bool Hand::hasFourKind(Card board[])

Have this

 bool Hand::hasFourKind(const Card *board)

This passes a pointer to the start of the array instead of making an array copy?

In most cases, if you don't need a local variable to be modified, the latter method of the first example is faster, because the entire object will not have to be copied on the stack for the function to use it. Instead, a pointer will be pushed onto the stack, which takes less time. (Although some calling conventions allow passing small arguments in registers, which is even faster.)

For small objects, the time spent in copying may not be an issue, but may be more evident for large classes/structs.

The second examples have identical operation (disregarding the const ness), since the array would not be passed by value in any case. It would be passed as a simple pointer, or passed "by reference."

From an optimisation point of view, the compiler can not rely on const actually meaning "won't change". const_cast allows a function to alter the const-ness of something, such that it can be altered. It is useful for the programmer to know that "I get an error if I accidentally modify this" (in particular mistyping if (a = b) instead of if (a == b) ).

If the source code of a function is available to the compiler, it can itself prove that a value isn't being changed, or is being changed, regardless of whether you mark it const or not.

In a video with Chandler Carruth (one of the currently most active developers of Clang and LLVM), he actually promotes using non-reference calls for any type that is reasonably small. Often, the compiler will optimise away the copy of the argument anyways, because the reference MAY be modified [so if the compiler doesn't have the source code available, it won't know if the value is being changed or not]

Whether you use Card board[] or Card *board will not change things, the compiler will generate exactly the same code either way - if you want others reading the code to understand if the function is expected to modify the value or not, then add const for values that aren't being changed.

This

Hand::Hand(const Card &one, const Card &two)

is more efficient than this

Hand::Hand(Card one, Card two)

For 2 reasons

  1. it avoids making a copy of the Cards
  2. If you wanted to maintain a Deck of cards, it is possibe with the first method but not possible with the second method for reasons explained by my first point

This

bool Hand::hasFourKind(Card board[])

is equivalent to this

bool Hand::hasFourKind(const Card *board)

because they both represent array of cards, but the first one is just syntatic sugar for pointer to cards, so they both actually represent pointer to cards.

The second is better because it implies that the board cannot be modified by anyone else. This is not really much of a guard because of const_cast which can be used to remove the constness of an object. If you really wanted to ensure that the cards cannot be modified by anybody in that method, then I would suggest you change design a bit to enable this:

bool Hand::hasFourKind() const;

Where the cards are part of the Hand class and cannot be modified by anyone

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