问题
when I do this (in my class)
public:
Entity()
{
re_sprite_eyes = new sf::Sprite();
re_sprite_hair = new sf::Sprite();
re_sprite_body = new sf::Sprite();
}
private:
sf::Sprite* re_sprite_hair;
sf::Sprite* re_sprite_body;
sf::Sprite* re_sprite_eyes;
Everything works fine. However, if I change the declarations to this:
private:
sf::Sprite* re_sprite_hair, re_sprite_body, re_sprite_eyes;
I get this compiler error:
error: no match for 'operator=' in '((Entity*)this)->Entity::re_sprite_eyes = (operator new(272u), (<statement>, ((sf::Sprite*)<anonymous>)))
And then it says candidates for re_sprite_eyes are sf::Sprite objects and/or references.
Why does this not work? Aren't the declarations the same?
回答1:
sf::Sprite* re_sprite_hair, re_sprite_body, re_sprite_eyes;
Does not declare 3 pointers - it is one pointer and 2 objects.
sf::Sprite* unfortunately does not apply to all the variables declared following it, just the first. It is equivalent to
sf::Sprite* re_sprite_hair;
sf::Sprite re_sprite_body;
sf::Sprite re_sprite_eyes;
You want to do:
sf::Sprite *re_sprite_hair, *re_sprite_body, *re_sprite_eyes;
You need to put one star for each variable. In such cases I prefer to keep the star on the variable's side, rather than the type, to make exactly this situation clear.
回答2:
In both C and C++, the * binds to the declarator, not the type specifier. In both languages, declarations are based on the types of expressions, not objects.
For example, suppose you have a pointer to an int named p, and you want to access the int value that p points to; you do so by dereferencing the pointer with the unary * operator, like so:
x = *p;
The type of the expression *p is int; thus, the declaration of p is
int *p;
This is true no matter how many pointers you declare within the same declaration statement; if q and r also need to be declared as pointers, then they also need to have the unary * as part of the declarator:
int *p, *q, *r;
because the expressions *q and *r have type int. It's an accident of C and C++ syntax that you can write T *p, T* p, or T * p; all of those declarations will be interpreted as T (*p).
This is why I'm not fond of the C++ style of declaring pointer and reference types as
T* p;
T& r;
because it implies an incorrect view of how C and C++ declaration syntax works, leading to the exact kind of confusion that you just experienced. However, I've written enough C++ to realize that there are times when that style does make the intent of the code clearer, especially when defining container types.
But it's still wrong.
回答3:
In C++11 you have a nice little workaround, which might be better than shifting spaces back and forth:
template<typename T> using type=T;
template<typename T> using func=T*;
// I don't like this style, but type<int*> i, j; works ok
type<int*> i = new int{3},
j = new int{4};
// But this one, imho, is much more readable than int(*f)(int, int) = ...
func<int(int, int)> f = [](int x, int y){return x + y;},
g = [](int x, int y){return x - y;};
回答4:
Another thing that may call your attention is the line:
int * p1, * p2;This declares the two pointers used in the previous example. But notice that there is an asterisk (
*) for each pointer, in order for both to have typeint*(pointer to int). This is required due to the precedence rules. Note that if, instead, the code was:int * p1, p2;
p1would indeed be of typeint*, butp2would be of typeint. Spaces do not matter at all for this purpose. But anyway, simply remembering to put one asterisk per pointer is enough for most pointer users interested in declaring multiple pointers per statement. Or even better: use a different statemet for each variable.
From http://www.cplusplus.com/doc/tutorial/pointers/
回答5:
The asterisk binds to the pointer-variable name. The way to remember this is to notice that in C/C++, declarations mimic usage.
The pointers might be used like this:
sf::Sprite *re_sprite_body;
// ...
sf::Sprite sprite_bod = *re_sprite_body;
Similarly,
char *foo[3];
// ...
char fooch = *foo[1];
In both cases, there is an underlying type-specifier, and the operator or operators required to "get to" an object of that type in an expression.
来源:https://stackoverflow.com/questions/13618282/declaring-multiple-object-pointers-on-one-line-causes-compiler-error