very handy links
February 8, 2009
http://code.google.com/p/chipmunk-physics/
http://code.google.com/p/cocos2d-iphone/wiki/GamesUsingCocos2d
Cool!!!
September 23, 2008
Take a look:
What are some advantages of using friend classes?
September 9, 2008
Friend classes are useful when a class wants to hide features from users that are needed only by another, tightly coupled class. Compared to making a member public:, it is sometimes better to make the member private:, which eliminates potential misuse by unknown users, and grant friendship status to the tightly cohesive class, thereby keeping implementation details hidden from the rest of the world.
Friend classes also arise when a member function on a class needs to maintain state between calls and when multiple copies of this state must exist. Under these circumstances, the member function becomes a friend class, and the multiple copies of the state become multiple objects of the friend class.
What is a friend?
September 9, 2008
A friend is an entity to which a class grants access authority.
Friends can be functions, other classes, or individual member functions of other classes. Friend classes are used when two or more classes are designed to work together and need access to each other’s implementation in ways that the rest of the world shouldn’t be allowed to have.
A very simple and fairly robust solution is to change the static data member into a static member function that returns a reference to a dynamically allocated object. This provides construct on first use semantics, which is desirable in many situations.
The following code shows how to apply this technique to the example from the previous FAQ. The static data member Wilma Fred::wilma_ has been changed to a static member function, Wilma& Fred::wilma(), and all uses of Fred::wilma_ have been changed to Fred::wilma(). Class Wilma is not shown since it is unchanged from the example in the previous FAQ.
class Fred {
public:
Fred() throw();
protected:
static Wilma& wilma() throw(); <– 1
};
inline Fred::Fred() throw()
{
cout << “Fred ctor\n”;
wilma().f(); <– 2
}
Fred x;
Wilma& Fred::wilma() throw() <– 3
{
static Wilma* p = new Wilma(); <– 4
return *p;
}
(1) Used to be static Wilma wilma_;
(2) Used to be wilma_.f()
(3) Used to be Wilma Fred::wilma_;
(4) Don’t forget the “static”!
In the static member function Fred::wilma(), pointer p is static, so the new Wilma() object is allocated only the first time that Fred::wilma() is called. All subsequent calls simply return a reference to the same Wilma object.
As shown in the (annotated) output from this program, the Wilma object is initialized before it is used. This is good.
Fred ctor
Wilma ctor <– 1
Wilma used <– 2
(1) The static object is constructed
(2) The static object is used
Is it safe to be ignorant of the static initialization order problem?
September 9, 2008
In the following example, the order of the global Fred and the static data member have been arranged to simulate this disaster.
#include
using namespace std;
class Wilma {
public:
Wilma() throw();
void f() throw();
};
inline Wilma::Wilma() throw() { cout << “Wilma ctor\n”; }
inline void Wilma::f() throw() { cout << “Wilma used\n”; }
class Fred {
public:
Fred() throw();
protected:
static Wilma wilma_;
};
inline Fred::Fred() throw()
{
cout << “Fred ctor\n”;
wilma_.f();
}
Fred x;
Wilma Fred::wilma_;
int main()
{ }
The (annotated) output from this program shows that the Wilma object is used before it is initialized. This is a disaster.
Fred ctor
Wilma used <– 1
Wilma ctor <– 2
(1) The static object is used
(2) The static object is constructed
Can an object legally be changed even though there is a const reference (pointer) to it?
September 8, 2008
Yes, due to aliasing.
The const part restricts the reference (pointer); it does not restrict the object. Many programmers erroneously think that the object on the other end of a const reference (pointer) cannot change. For example, if const int& i refers to the same int as int& j, j can change the int even though i cannot. This is called aliasing, and it can confuse programmers who are unaware of it.
#include
using namespace std;
void sample(const int& i, int& j) throw()
{
int orig = i;
j++; <– 1
if (i != orig)
cout << “The value of i is different!\n”;
}
int main()
{
int x = 3;
sample(x, x);
}
(1) Incrementing j can change the int called i
There is no rule in C++ that prohibits this sort of thing. In fact, it is considered a feature of the language that programmers can have several pointers or references refer to the same object (plus it could not be figured out in some cases, e.g., if there are intermediate functions between main() and sample(const int&,int&) and if these functions are defined in different source files and are compiled on different days of the week). The fact that one of those references or pointers is restricted from changing the underlying object is a restriction on the reference (or pointer), not on the object.
What’s the difference between an inspector and a mutator?
September 8, 2008
An inspector is a member function that returns information about an object’s state without changing the object’s abstract state (that is, calling an inspector does not cause an observable change in the behavior of any of the object’s member functions). A mutator changes the state of an object in a way that is observable to outsiders: it changes the object’s abstract state. Here is an example.
class Stack {
public:
int pop(); //Mutator
int numElems() const; //Inspector
};
The pop() member function is a mutator because it changes the Stack by removing the top element. The numElems() member function is an inspector because it simply counts the number of elements in the Stack without making any observable changes to the Stack. The const decoration after numElems() indicates that numElems() promises not to change the Stack object.
Only inspectors may be called on a reference-to-const or pointer-to-const:
void sample(const Stack& s) throw()
{
s.numElems(); // OK: A const Stack can be inspected
#ifdef GENERATE_ERROR
s.pop(); // Error: A const Stack cannot be mutated
#endif
}
How can C++ programmers avoid making unexpected changes to objects?
September 8, 2008
With proper use of the keyword const, the C++ compiler detects many unexpected changes to objects and flags these violations with error messages at compile time. This is often called const correctness. For example, function f() uses the const keyword to restrict itself so that it won’t be able to change the caller’s string object:
#include
using namespace std;
void f(const string& s) throw(); // Parameter is received
// by reference-to-const
If f() changes its passed string anyway, the compiler flags it as an error at compile time:
void f(const string& s) throw()
{
#ifdef GENERATE_ERROR
s += “foo”; <– 1
#endif
}
(1) Error: The string cannot be mutated via s
In contrast, function g() declares its intent to change the caller’s string object by its lack of the const keyword in the appropriate place:
void g(string& s) throw(); // Parameter is received by
// reference-to-non-const
For example, it is legal and appropriate for g() to modify the caller’s string object:
void g(string& s) throw()
{
s += “foo”; // OK: Modifies the caller’s string object
}
Also it would be legal and appropriate for g() to pass its parameter to f(), since the called function, f(), is at least as restrictive as the caller, g() (in this case, the called function is actually more restrictive):
void g(string& s) throw()
{
f(s); // OK (though it doesn’t happen to modify
// caller’s string object)
s += “foo”; // OK: Modifies the caller’s string object
}
However, it would be illegal for the opposite to occur. That is, if f() passed its parameter to g(), the compiler would give an error message since the called function, g(), is less restrictive than the caller, f():
void f(const string& s) throw()
{
#ifdef GENERATE_ERROR
g(s); <– 1
#endif
}
(1) Error: The const string& cannot be passed as a string&
How should pointer declarations be read?
September 8, 2008
Pointer declarations should be read right to left.
If Fred is some type, then
Fred* is a pointer to a Fred (the * is pronounced “pointer to a”).
const Fred* is a pointer to a Fred that cannot be changed via that pointer.
Fred* const is a const pointer to a Fred. The Fred object can be changed via the pointer, but the pointer itself cannot be changed.
const Fred* const is a const pointer to a Fred that cannot be changed via that pointer.
References are similar: read them right to left.
Fred& is a reference to a Fred (the & is pronounced “reference to a”).
const Fred& is a reference to a Fred that cannot be changed via that reference.
Note that Fred& const and const Fred& const are not included in the second list. This is because references are inherently immutable: you can never rebind the reference so that it refers to a different object.