9

I've just read the new operator explanation on the cplusplus.com. The page gives an example to demonstrate four different ways of using new operator as following:

// operator new example
#include <iostream>
#include <new>
using namespace std;

struct myclass {myclass() {cout <<"myclass constructed\n";}};

int main () {

   int * p1 = new int;
// same as:
// int * p1 = (int*) operator new (sizeof(int));

   int * p2 = new (nothrow) int;
// same as:
// int * p2 = (int*) operator new (sizeof(int),nothrow);

   myclass * p3 = (myclass*) operator new (sizeof(myclass));
// (!) not the same as:
// myclass * p3 = new myclass;
// (constructor not called by function call, even for non-POD types)

   new (p3) myclass;   // calls constructor
// same as:
// operator new (sizeof(myclass),p3)

   return 0;
}

My questions are:

  1. What is the best practice of using new operator?
  2. Is myclass* p3 = new myclass equivalent to myclass* p3 = new myclass()?
Melebius
  • 6,183
  • 4
  • 39
  • 52
xiao 啸
  • 6,350
  • 9
  • 40
  • 51
  • 8
    There is no "best practice" - you have to know what you are doing. Or you could not use new at all - many useful C++ programs can and should be written without using it. –  May 13 '11 at 17:38
  • 2
    This thread should answer your second question. http://stackoverflow.com/questions/620137/do-the-parentheses-after-the-type-name-make-a-difference-with-new – Mahesh May 13 '11 at 17:39
  • 2
    In when you truly need dynamic allocation, do use a smart pointer. – GManNickG May 13 '11 at 17:40
  • @Neil, well, I mean the guideline to determine which usage of new operator to take. – xiao 啸 May 13 '11 at 17:40
  • 1
    @xiao I suspect that english is not your first language, so I'll rephrase - there is no general guideline, it depends what your code is intended (by you) to do. –  May 13 '11 at 17:44
  • 4
    C++ isn't a simple language. If he thinks this is confusing, wait 'till he discovers that it is possible to create a protected abstract virtual base pure virtual private destructor. – T.E.D. May 13 '11 at 17:48

4 Answers4

6

Because they have different purposes. If you didn't want new to throw std::bad_alloc on failure, you would use nothrow. If you wanted to allocate your objects in existing storage, you would use placement new … if you want raw, uninitialized memory, you would invoke operator new directly and cast the result to the target type.

The plain standard usage of new in 99% of all cases is MyClass* c = new MyClass();

To your second question: the new Object() vs. new Object forms are not generally equal. See this question and the responses for the details. But that really is nitpicking. Usually they are equivalent, but to be on the safe side always pick new Object(); Note that, in this particular sample they are equal because MyClass doesn't have any members, so strictly speaking the answer to your question is yes.

Community
  • 1
  • 1
Alexander Gessler
  • 45,603
  • 7
  • 82
  • 122
2

1) Several of these are used only in specific, unusual situations. The plain old traditional one is best, most of the time anyway:

X * x = new X();

2) Yes, they are. If the constructor has no arguments, the parentheses are optional. If you're declaring an automatic variable -- i.e.,

X x;

then you must omit the parentheses, or it's a function declaration! As a result, many people will tell you to omit them in the new expression as well. That's a good practice, I think, but I'm just used to including them.

Ernest Friedman-Hill
  • 80,601
  • 10
  • 150
  • 186
0

Rather than "best practice", you need them in different situations. For example, most people just want to call new x() to allocate some memory and create the object. However, sometimes you're in situations where you don't want an exception thrown in case new fails, so you call new (nothrow) instead to get a null back.

If you already have some memory allocated but need to create an object, you use "placement new" by calling new (p3) x.

In the rare case where you need to use a class's memory allocator but not actually create an object, you use the (myclass*) operator new (sizeof(myclass)) syntax.

Gabe
  • 84,912
  • 12
  • 139
  • 238
0

Here are my recommendations:

  1. Prefer not to use new; pass by reference when possible. (Avoids memory leaks).
  2. Use operator new: x = new X(); // Remember to use delete
  3. Prefer std::vector to array new: x = new X()[quantity]; // Remember to use delete []
  4. Don't use placement new unless you absolutely know the reasons.

In general, placement new is used to allocate from specific addresses or a special memory pool. This is an advanced topic.

Thomas Matthews
  • 56,849
  • 17
  • 98
  • 154