*new or new?

R

Ron Natalie

Nick Hounsome said:
The advantage of references is the gaurantee (in the absence of people dong
the above) that the reference is valid.
This is very helpful when dealing with analy retentive coding standards that
insist that you check all pointers for null on entry.

Of course, that just moves the undefined behavior around. If someone was
likely to have passed a null pointer to a function unprepared to handle it, he was
probably just as likely to dereference it in his code and pass you a reference to
a "null" object.
The issue is not pointer versus reference so much as dynamic versus non-dynamic
storage duration. The latter is clearly preferable, and even dynamic storage is
better off handled by wrapping it in some non-dynamic class.
 
J

Jeff Schwab

Nick said:
There is a difference - the pointer can be set to 0 and subsequently tested.
Indeed it is common to write stuff like:
if( !p ) p = new P();
There is no equivalent for references.

That's not what the OP was doing. References and pointers are *not* the
same thing; however, I know of no problem with binding *new to a
reference, and your example does not demonstrate one. It only shows a
pointer being used in a way that a reference cannot. Often, references
make more sense than pointers for this sort of thing. For example, it
is common to have a member pointer to some memory allocated by the
constructor. In this case, the memory typically is deallocated in the
destructor, and there is no point in resetting the pointer to null. In
fact, I find references preferable to pointers in this case, since you
will get a compile-time error if you forget to allocate the memory. If
you forget to initialize the pointer, the error will not occur until
run-time; such bugs can be horribly pernicious.
The advantage of references is the gaurantee (in the absence of people dong
the above) that the reference is valid.

There is no such guarantee.
This is very helpful when dealing with analy retentive coding standards that
insist that you check all pointers for null on entry.

Blame the coding standard, not the initialiation of references with
dynamically allocated memory.
One advantage of pointers is that you can put them in an auto_ptr and forget
them. (Of course you could write an equivalent for your references).
Another is that you can use 0 to mean something - either as a parameter when
it usualy means 'use defaults' or as a member when it means 'not yet
initialized'

Yes, pointers certainly have the advantage over references in many (but
not all) cases.
I have found a more serious argument: consider

AnyClass& reg=*new DerivedFromAnyClass();

The standard states that the implementation can (implementation defined)
bind to the AnyClass subobject of a temporary copy.
This would obviously be a disaster since the original would leak and delete
&reg would try to deallocate something on the stack.

Only if the destructor is non-virtual. The same argument can be made
against pointers. This is not a reference-specific problem.
P.S. The equivalent to
AnyClass& reg=*new AnyClass();
is
AnyClass * const pReg=new AnyClass();
not
AnyClass *pReg=new AnyClass();

Because the latter can be rebound unlike the reference

Again, the OP was not looking to "rebind the reference." You've
mentioned cases where pointers are needed. If your point is that
references cannot entirely replace pointers, I wholeheartedly agree.
However, I still see nothing wrong with either of the OP's offerings.

-Jeff
 
N

Nick Hounsome

Ron Natalie said:
Of course, that just moves the undefined behavior around. If someone was
likely to have passed a null pointer to a function unprepared to handle it, he was
probably just as likely to dereference it in his code and pass you a reference to
a "null" object.

You miss the point - I don't have to check references even if they are bad
because there is no way to check them hence my code isn't littered with
tests that obscure the logic.
The issue is not pointer versus reference so much as dynamic versus non-dynamic
storage duration. The latter is clearly preferable, and even dynamic storage is
better off handled by wrapping it in some non-dynamic class.

reference to dynamic is not the same as non-dynamic.

The wrapper for dynamic is calld std::auto_ptr
 
N

Nick Hounsome

[]
Only if the destructor is non-virtual. The same argument can be made
against pointers. This is not a reference-specific problem.

No - the standard says (goodness knows why) that this can be implemented as:

DerivedFromAnyClass temp = *new DerivedFromAnyClass();
AnyClass& reg = temp;

i.e. regardless of virtual dtors the dynamically allocated object is leaked
and
delete &reg trys to free a non-heap object.
 
J

Jeff Schwab

Nick said:
[]
delete


Only if the destructor is non-virtual. The same argument can be made
against pointers. This is not a reference-specific problem.


No - the standard says (goodness knows why) that this can be implemented as:

DerivedFromAnyClass temp = *new DerivedFromAnyClass();
AnyClass& reg = temp;

i.e. regardless of virtual dtors the dynamically allocated object is leaked
and
delete &reg trys to free a non-heap object.

Wow, that's news to me. Do you happen to know of any compilers that
actually do that? This is fine in GCC:

/* Output is:
* ~B
* ~A
*/
#include <iostream>

struct A { virtual ~A( ) { std::cerr << "~A\n"; } };
struct B: A { ~B( ) { std::cerr << "~B\n"; } };

int main( )
{
A& a = *new B;

delete &a;
}
 
J

Jeff Schwab

Nick said:
[]
delete


Only if the destructor is non-virtual. The same argument can be made
against pointers. This is not a reference-specific problem.


No - the standard says (goodness knows why) that this can be implemented as:

DerivedFromAnyClass temp = *new DerivedFromAnyClass();
AnyClass& reg = temp;

Btw, what section of the standard is this?

Thanks,
Jeff
 
R

Ron Natalie

Jeff Schwab said:
int main( )
{
A& a = *new B;

delete &a;

The original premise is wrong. &a is NOT a heap object. It's the legitimate address
of the A subobject of the dynamically allocated B.
 
N

Nick Hounsome

Jeff Schwab said:
Nick said:
[]
I have found a more serious argument: consider

AnyClass& reg=*new DerivedFromAnyClass();

The standard states that the implementation can (implementation defined)
bind to the AnyClass subobject of a temporary copy.
This would obviously be a disaster since the original would leak and
delete

&reg would try to deallocate something on the stack.

Only if the destructor is non-virtual. The same argument can be made
against pointers. This is not a reference-specific problem.


No - the standard says (goodness knows why) that this can be implemented as:

DerivedFromAnyClass temp = *new DerivedFromAnyClass();
AnyClass& reg = temp;

Btw, what section of the standard is this?

reference is 8.5.3 para 5

On closer inspection I think it is only a problem if the cv qualifiers
differ i.e.
const AnyClass& reg = *new DerivedFromAnyClass;
or is it
AnyClass& reg = *new const DerivedFromAnyClass; ????

but then that just confirms my general approach which is not to delve into
unusual corners of the language where you need to check the standard unless
strictly necessary.
 
J

Jeff Schwab

Ron said:
Gak...that should read &a IS a heap object. It is not a STACK object.

Did someone imply otherwise? Do you know of anything wrong with the
above code?
 
J

Jorge Rivera

I would always go for number 2.

First of all, you are allocating a pointer.

Why in the world would you want to create a reference to it without
keeping track of what is the memory location of this pointer?

Who will handle the memory deallocation of your newly allocate pointer?

By the way, have you thought of doing?

std::auto_ptr<AnyClass> reg(new AnyClass());
*reg.Function();
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Similar Threads

Can't spot source of corruption! 3
Returning by value (here we go again!) 11
AnyClass 11
Newbie question 5
Calling a constructor? 10
New Learner 0
C++ cryptography new library 0
Need Assistance With A Coding Problem 0

Members online

No members online now.

Forum statistics

Threads
474,159
Messages
2,570,883
Members
47,414
Latest member
djangoframe

Latest Threads

Top