UPDATE
This answer is rather old, and so describes what was 'good' at the time, which was smart pointers provided by the Boost library. Since C++11, the standard library has provided sufficient smart pointers types, and so you should favour the use of std::unique_ptr
, std::shared_ptr
and std::weak_ptr
.
There was also std::auto_ptr
. It was very much like a scoped pointer, except that it also had the "special" dangerous ability to be copied — which also unexpectedly transfers ownership.
It was deprecated in C++11 and removed in C++17, so you shouldn't use it.
std::auto_ptr<MyObject> p1 (new MyObject());
std::auto_ptr<MyObject> p2 = p1; // Copy and transfer ownership.
// p1 gets set to empty!
p2->DoSomething(); // Works.
p1->DoSomething(); // Oh oh. Hopefully raises some NULL pointer exception.
OLD ANSWER
A smart pointer is a class that wraps a 'raw' (or 'bare') C++ pointer, to manage the lifetime of the object being pointed to. There is no single smart pointer type, but all of them try to abstract a raw pointer in a practical way.
Smart pointers should be preferred over raw pointers. If you feel you need to use pointers (first consider if you really do), you would normally want to use a smart pointer as this can alleviate many of the problems with raw pointers, mainly forgetting to delete the object and leaking memory.
With raw pointers, the programmer has to explicitly destroy the object when it is no longer useful.
// Need to create the object to achieve some goal
MyObject* ptr = new MyObject();
ptr->DoSomething(); // Use the object in some way
delete ptr; // Destroy the object. Done with it.
// Wait, what if DoSomething() raises an exception...?
A smart pointer by comparison defines a policy as to when the object is destroyed. You still have to create the object, but you no longer have to worry about destroying it.
SomeSmartPtr<MyObject> ptr(new MyObject());
ptr->DoSomething(); // Use the object in some way.
// Destruction of the object happens, depending
// on the policy the smart pointer class uses.
// Destruction would happen even if DoSomething()
// raises an exception
The simplest policy in use involves the scope of the smart pointer wrapper object, such as implemented by boost::scoped_ptr
or std::unique_ptr
.
void f()
{
{
std::unique_ptr<MyObject> ptr(new MyObject());
ptr->DoSomethingUseful();
} // ptr goes out of scope --
// the MyObject is automatically destroyed.
// ptr->Oops(); // Compile error: "ptr" not defined
// since it is no longer in scope.
}
Note that std::unique_ptr
instances cannot be copied. This prevents the pointer from being deleted multiple times (incorrectly). You can, however, pass references to it around to other functions you call.
std::unique_ptr
s are useful when you want to tie the lifetime of the object to a particular block of code, or if you embedded it as member data inside another object, the lifetime of that other object. The object exists until the containing block of code is exited, or until the containing object is itself destroyed.
A more complex smart pointer policy involves reference counting the pointer. This does allow the pointer to be copied. When the last "reference" to the object is destroyed, the object is deleted. This policy is implemented by boost::shared_ptr
and std::shared_ptr
.
void f()
{
typedef std::shared_ptr<MyObject> MyObjectPtr; // nice short alias
MyObjectPtr p1; // Empty
{
MyObjectPtr p2(new MyObject());
// There is now one "reference" to the created object
p1 = p2; // Copy the pointer.
// There are now two references to the object.
} // p2 is destroyed, leaving one reference to the object.
} // p1 is destroyed, leaving a reference count of zero.
// The object is deleted.
Reference counted pointers are very useful when the lifetime of your object is much more complicated, and is not tied directly to a particular section of code or to another object.
There is one drawback to reference counted pointers — the possibility of creating a dangling reference:
// Create the smart pointer on the heap
MyObjectPtr* pp = new MyObjectPtr(new MyObject())
// Hmm, we forgot to destroy the smart pointer,
// because of that, the object is never destroyed!
Another possibility is creating circular references:
struct Owner {
std::shared_ptr<Owner> other;
};
std::shared_ptr<Owner> p1 (new Owner());
std::shared_ptr<Owner> p2 (new Owner());
p1->other = p2; // p1 references p2
p2->other = p1; // p2 references p1
// Oops, the reference count of of p1 and p2 never goes to zero!
// The objects are never destroyed!
To work around this problem, both Boost and C++11 have defined a weak_ptr
to define a weak (uncounted) reference to a shared_ptr
.
The return value for main
indicates how the program exited. Normal exit is represented by a 0 return value from main
. Abnormal exit is signaled by a non-zero return, but there is no standard for how non-zero codes are interpreted. As noted by others, void main()
is prohibited by the C++ standard and should not be used. The valid C++ main
signatures are:
int main()
and
int main(int argc, char* argv[])
which is equivalent to
int main(int argc, char** argv)
It is also worth noting that in C++, int main()
can be left without a return-statement, at which point it defaults to returning 0. This is also true with a C99 program. Whether return 0;
should be omitted or not is open to debate. The range of valid C program main signatures is much greater.
Efficiency is not an issue with the main
function. It can only be entered and left once (marking the program's start and termination) according to the C++ standard. For C, re-entering main()
is allowed, but should be avoided.
Best Answer
static_cast
is the first cast you should attempt to use. It does things like implicit conversions between types (such asint
tofloat
, or pointer tovoid*
), and it can also call explicit conversion functions (or implicit ones). In many cases, explicitly statingstatic_cast
isn't necessary, but it's important to note that theT(something)
syntax is equivalent to(T)something
and should be avoided (more on that later). AT(something, something_else)
is safe, however, and guaranteed to call the constructor.static_cast
can also cast through inheritance hierarchies. It is unnecessary when casting upwards (towards a base class), but when casting downwards it can be used as long as it doesn't cast throughvirtual
inheritance. It does not do checking, however, and it is undefined behavior tostatic_cast
down a hierarchy to a type that isn't actually the type of the object.const_cast
can be used to remove or addconst
to a variable; no other C++ cast is capable of removing it (not evenreinterpret_cast
). It is important to note that modifying a formerlyconst
value is only undefined if the original variable isconst
; if you use it to take theconst
off a reference to something that wasn't declared withconst
, it is safe. This can be useful when overloading member functions based onconst
, for instance. It can also be used to addconst
to an object, such as to call a member function overload.const_cast
also works similarly onvolatile
, though that's less common.dynamic_cast
is exclusively used for handling polymorphism. You can cast a pointer or reference to any polymorphic type to any other class type (a polymorphic type has at least one virtual function, declared or inherited). You can use it for more than just casting downwards – you can cast sideways or even up another chain. Thedynamic_cast
will seek out the desired object and return it if possible. If it can't, it will returnnullptr
in the case of a pointer, or throwstd::bad_cast
in the case of a reference.dynamic_cast
has some limitations, though. It doesn't work if there are multiple objects of the same type in the inheritance hierarchy (the so-called 'dreaded diamond') and you aren't usingvirtual
inheritance. It also can only go through public inheritance - it will always fail to travel throughprotected
orprivate
inheritance. This is rarely an issue, however, as such forms of inheritance are rare.reinterpret_cast
is the most dangerous cast, and should be used very sparingly. It turns one type directly into another — such as casting the value from one pointer to another, or storing a pointer in anint
, or all sorts of other nasty things. Largely, the only guarantee you get withreinterpret_cast
is that normally if you cast the result back to the original type, you will get the exact same value (but not if the intermediate type is smaller than the original type). There are a number of conversions thatreinterpret_cast
cannot do, too. It's used primarily for particularly weird conversions and bit manipulations, like turning a raw data stream into actual data, or storing data in the low bits of a pointer to aligned data.C-style cast and function-style cast are casts using
(type)object
ortype(object)
, respectively, and are functionally equivalent. They are defined as the first of the following which succeeds:const_cast
static_cast
(though ignoring access restrictions)static_cast
(see above), thenconst_cast
reinterpret_cast
reinterpret_cast
, thenconst_cast
It can therefore be used as a replacement for other casts in some instances, but can be extremely dangerous because of the ability to devolve into a
reinterpret_cast
, and the latter should be preferred when explicit casting is needed, unless you are surestatic_cast
will succeed orreinterpret_cast
will fail. Even then, consider the longer, more explicit option.C-style casts also ignore access control when performing a
static_cast
, which means that they have the ability to perform an operation that no other cast can. This is mostly a kludge, though, and in my mind is just another reason to avoid C-style casts.