简体   繁体   中英

Widget wag = *new Widget()

I just came across a C++ SDK that makes heavy use of this really weird *new pattern. I dont understand why they do it like that at all.

What's the point of constructing objects with *new, eg Widget wag = *new Widget(); ?

Update: Interesting, they are actually doing XPtr<T> p = *new T; - must be the semantics of some smart pointer magic. Still doesn't make much sense. I do trust the SDK is high quality.

Maybe they're trying for memory leaks? With the default implementation of new that will allocate a Widget on the heap, then copy construct wag from it, then it will promptly leak the new object.

Bottom line: don't imitate. And I would regard that SDK with suspicion.

Edit: If this is done in the context of a smart pointer, then it's certainly possible they're saving the pointer for later deletion. If there's an XPtr template that's doing that, you should be able to look at the code and see if that's what it's doing. The SDK should also provide you some kind of documentation somewhere about that construct, since it isn't normal, and I don't really see much advantage to it. Still, I stand by what I said: even though it's not a guaranteed leak, I still wouldn't imitate it.

It constructs a new object and then makes a copy of it. The pointer to the original object is discarded, so there may be a memory leak.

There isn't necessarily a memory leak, though. It could be that Widget maintains a list of all its instances, and it updates that list in its constructor and destructor. There might be some other way of attaining the contents of the list.

But it seems rather pointless. The reason was probably due to a misunderstanding of how the code really works. Your best bet for finding out why the code was made that way is to ask the ones who wrote it. There might be clues in the code's comments. Can you reveal more specifics about what code you're looking at?

This basically does this:

Widget wag = *(new Widget());

// or
Widget wag;

I don't know if this will properly free it or not. My guess it wouldn't.

To answer your question, I feel its poor design choice. Probably they wanted to start using pointers, but then just got ugly.

A commom smart pointer pattern for ref-counted objects is that the following code will store the object and IncRef it:

SmartPtr<Type> ptr = new Type();

And the following code will store the object and not IncRef it:

SmartPtr<Type> ptr = *new Type();

The second form is useful if the object's constructor applies the first IncRef. Otherwise, your object would have a ref count of 2 and when the smart pointer went out of scope, it still wouldn't free the object.

No idea if this is the case in the library you're using. A quick perusal of the XPtr code would probably tell you, though.

It's not necessarily leaking. For example consider the following

int &a = *new int();
delete &a;

It's assigning to a reference. It will preserve the identity of the object created (not creating a copy), so it will not lose track of it, and will delete it fine afterwards. Putting it into the form of your code, that class could be defined as

template<typename T>
struct XPtr {
    T *ptr;
    XPtr(T &t):ptr(&t) { }
    ~XPtr() { delete ptr; }
};

...
XPtr<T> p = *new T;

Or even more complex, with reference counting - so that p can be copied, and XPtr keeps track of all its copies, and so on.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM