Dumb question, but whenever you call new, do you always have a pointer?开发者_开发技巧
SomeClass *person = new SomeClass();
And is that because you need a pointer to point to that new space of memory that was allocated for the SomeClass variable person? Thanks!
If new
completes successfully, it always returns a pointer (if it doesn't complete successfully, an exception is thrown, and nothing is returned).
The pointer is to the object that was created, or in the case of an array, a pointer to the first element of the array.
Yes, always a pointer. Even if you want to overload new, return type must be void*.
And you are right about purpose
new creates an object on the heap and all it can return is its address - a pointer.
Yes. If you are asking why it doesn't return a reference instead, since references are nicer than pointers, the answer is historical heritage.
When C++ was in development, if the machine was unable to get memory for the object, a special pointer NULL
was returned. This is how it is done in C:
SomeClass *person;
person = (SomeClass*) malloc( sizeof( SomeClass ) );
if ( person == NULL ) fprintf( stderr, "no more people allowed!" );
In standard C++, errors are returned by exception instead:
try {
SomeClass *person = new SomeClass;
// do something
} catch ( std::bad_alloc ) {
std::cerr << "no more people!" << std::endl;
} catch ( ... ) {
// using exceptions allows for other errors
// from inside SomeClass::SomeClass too
}
You can still do it the old-fashioned way, though, with nothrow
:
SomeClass *person = new( std::nothrow ) SomeClass;
if ( person == NULL ) std::cerr << "no more people allowed!" << std::endl;
The upshot is, this is perfectly reasonable and good style:
SomeClass &person = * new SomeClass; // don't need no stinkin pointers!
The new expression returns a pointer, but you can use it with "smart pointer" classes (e.g. from Boost). So:
boost::shared_ptr<SomePerson> person(new SomePerson);
I should also point out that, though you may be used to using the parentheses if you come from a Java background, in C++, the parentheses are not needed when using the default constructor. So, for example, one ordinarily writes new T
when default constructing, but one writes new T(param)
, or new T(param1,...,paramN)
when constructing an object using a constructor other than the default.
Yes, that is correct; one could, theoretically, write (new SomePerson)->doSomething(), but that would be a memory leak; C++ does not have garbage collection, so it is necessary to store the result of the new expression in something (a pointer or a smart pointer) so that it can be properly deallocated.
精彩评论