I'm learning C++. I have a simple class named GameContext:
class GameContext {开发者_如何学编程
public:
GameContext(World world);
virtual ~GameContext();
};
To initialize a GameContext
object, I need a World
object.
Should the GameContext constructur take a pointer to a World object (
World*
), the address to a World object (&World
) or a reference to a World object (World)?What is the
const
keyword when used near a parameter? For example:GameContext(const World &world)
Thanks.
First, teminology: You're right that a World *
would be a pointer to a World object. A World &
, however, would be a reference to a World object. A World
would be a copy of the World object, not a reference to it.
The const
(used primarily with a pointer or reference, as in World const &world
or World const *world
) means that you're getting a reference/pointer to a const object -- in other words, you're not allowed to modify the original object to which it refers/points.
For small objects, you usually want to pass a copy. For large objects, you'll typically want to pass a const reference. There are exceptions to this, but that's a reasonable rule of thumb to use until you've learned enough more to know when to break the rules (so to speak).
Just based on the name, I'd guess your World object is probably large enough that you probably want to pass it by const reference, so your ctor should look like:
GameContext(World const &world);
Ideally, you should accept a const
reference to World
:
class GameContext {
public:
GameContext(const World& world);
virtual ~GameContext();
};
First, so that no copying happens when passing the world
. Second, const
is keyword that means that you aren't going to change the passed parameter which is world
in this case.
World
is not a reference to a World
object - the compiler is making a copy of the structure and passing it through the stack. This is bad.
A pointer (World*
) and a reference (World&
) are very similar, they differ only in syntax (->
vs .
) and scope (you can't assign a reference, so the member m_pWorld
can't point to another World during the lifetime of your GameContext if you use a reference - but you can do that if you use a pointer). My advice is get a reference if you'll always use the same World (likely), or a pointer otherwise.
The const
there tells the compiler you won't modify the object. When you get a reference to an object, you're working on the object, not a copy of it - so anything you modify in the method actually modifies the "outside" object. In your case, since you'll probably modify or otherwise operate on your World
within GameContext
, you probably want a non-const reference.
So you should do something like this
class GameContext
{
public:
GameContext (World& pWorld) : m_pWorld(pWorld)
{
}
virtual ~GameContext () { ... }
void foo (int nParam)
{
m_pWorld.bar(nParam);
}
private:
World& m_pWorld;
};
Your terminology is way off.
In C++ terminology the terms pointer and address are synonyms (as far as we are talking about values). In order to take the pointer (or the address) you have to declare your parameter as World* world
.
To take the reference, the parameter should be declared as World& world
.
To take a copied value, the parameter should be declared as World world
.
Which declaration you should use in each specific case depends on our intent. Assuming that World
is a non-trivial object, the choice should normally be limited to either reference World& world
or pointer World* world
.
If you don't intend to modify the source World
object in GameContext
's constructor, a const
should be added: const World& world
or const World* world
.
Finally, passing by pointer allows you to pass a "reserved" value - a null pointer - but at the same time prevents you from passing a pointer to a non-lvalue. If this does not matter much to you, then you should probably stick with a reference const World& world
.
Reference are safer than pointers and involve no copy. As for the const keyword read the answer to this question I made some time ago: How many and which are the uses of "const" in C++?
The const
means that the method GameContext
wont be able to modify the contents of the parameter world
Should the GameContext constructur take a pointer to a World object (World*), the address to a World object (&World) or a reference to a World object (World)?
First of all, the "address to a World
object" is the same thing as a pointer to a World
object. A pointer is a type of variable that stores an object's address. If you pass an address, then the parameter that corresponds to the address you passed will be a pointer.
Whether you want to take a pointer or not depends on the semantics of the World
class. If you take a value (and not a pointer), then you will receive a copy of the World object passed in. If something other than the GameContext
object needs to perform operations on that same world object, then you will want to pass in and store a pointer. If this is not necessary, or if the World
class operates internally such that all copies of a World
object use a common set of data, then you can pass by value.
What is the const keyword when used near a parameter? For example: GameContext(const World &world)
const
means "cannot be modified", just like it means anywhere else. A common idom in C++, as you have given in your example, is to take a constant reference instead of taking a value. When the parameter is an object (as opposed to a fundamental type like int
or bool
), this is more efficient than taking a value, since a copy is not made in this case. However the const
prevents the function from modifying the referenced parameter, so to the caller, it does not matter than it is a reference.
精彩评论