Always avoid "new"

E

E. Robert Tisdale

Default said:
Creating objects via new is of course very important in using
polymorphism and design patterns such as Abstract Factory.

Something else that should *always* be avoided.
 
E

E. Robert Tisdale

seesaw said:
Is it right thing to always avoid using "new" to create objects?
What if, after starting the application,
then decide which and how many objects to create?
(Seems like, under such situation,
there is no other choice but using "new")

The latest version of C specifies "variable length arrays".
It is possible -- perhaps probable -- that the new version of C++
will adopt variable length arrays as well.

Some C++ compiler already implement this as an extension:
cat main.cc
#include <iostream>

int main(int argc, char* argv[]) {
if (1 < argc) {
const
size_t n = atoi(argv[1]);
int a[n];
for (size_t j = 0; j < n; ++j)
a[j] = j;
for (size_t j = 0; j < n; ++j)
std::cout << a[j] << " = a[" << j << "]" << std::endl;
}
return 0;
}
g++ -Wall -o main main.cc
./main 10
0 = a[0]
1 = a[1]
2 = a[2]
3 = a[3]
4 = a[4]
5 = a[5]
6 = a[6]
7 = a[7]
8 = a[8]
9 = a[9]

This will make it *much* easier to avoid using new
in the situation that you are concerned about.
 
B

Bernhard Holzmayer

seesaw said:
Is it right thing to always avoid using "new" to create objects?
What if after starting the application, then decide which and how
many objects to create? (Seems like under such situation is there
no other choice but using "new")

No, this is certainly not right.

If you're not restricted by coding rules or other issues,
you should try to find the most appropriate approach which solves
your task.

Usually, the result depends on your experience, skill and often -
the striking thought which enlightens you....

If you end up with "new" being part of your solution, there's
nothing against it. It's part of the language, and it's there to be
used.

However, I'd advise you to handle it with care - nothing more.

If you make use of new (new[]), always check if the appropriate
delete(delete[]) operator is in place and works correctly.

Then check if you have implemented the correct means (pointers with
its necessary life-time) to keep control over the created objects.

And finally, have a close look to all sort of exceptions and
ill-conditions, which might confuse your usual program flow, so
that your deallocations don't fail.

Bernhard
 
M

Michiel Salters

E. Robert Tisdale said:
Something else that should *always* be avoided.

Now that is a statement which is even less backed by facts.

An Abstract Factory makes perfect sense, if the design requires
creation of objects whose type is not statically known. There
are well-known implementation issues (e.g. should return smart
pointer) but when these issues are avoided AF is the best
solution for that specific problem.

Regards,
Michiel Salters
 
E

E. Robert Tisdale

Michiel said:
Now that is a statement which is even less backed by facts.

An Abstract Factory makes perfect sense,
if the design requires creation of objects
whose type is not statically known.

These are very rare and special circumstances.
Before you use an "abstract factory",
you need to show that these circumstances *cannot* be avoided.
Otherwise, you are simply building in a hazard for yourself
and other programmers who must maintain your code.
 
T

tom_usenet

And wouldn't _that_ have been a mistake! The standard containers are a great
facility to have, but I doubt you honestly think that they're sufficient for all
needs and that mechanisms to create alternatives would have been removed from the
language even had containers been present from day one. Even the addition of
reasonable smart pointers wouldn't obviate the need for manual dynamic allocation
in certain contexts.

std::malloc (or ::eek:perator new)

new expressions are a bit odd - the array version calls the default
constructor, which is hardly helpful in general. You also have to
match your array and non-array versions. Seems like we could do
without it if we had another, more fundamental container type, like
"std::buffer" (with no capacity, just size). std::buffer could be used
to build std::vector!

Then there are the odd rules about overloading new, and the fact that
you can't call overloaded delete in the same way. It's a bit of a
mess...

Tom
 
J

jeffc

Andrew Koenig said:
Not really; I'd use std::allocator instead, because it gives me
finer-grained control over construction and destruction than new does.

OK you got me. But presumably you see my point anyway. The OP was asking
generically about new, and my point was there comes a time when you should
use it and need to know how to use it.
 
A

Andrew Koenig

new expressions are a bit odd - the array version calls the default
constructor, which is hardly helpful in general. You also have to
match your array and non-array versions. Seems like we could do
without it if we had another, more fundamental container type, like
"std::buffer" (with no capacity, just size). std::buffer could be used
to build std::vector!

What does std::allocator not do that you want?
 
M

Mark A. Gibbs

seesaw said:
Is it right thing to always avoid using "new" to create objects? What if
after starting the application, then decide which and how many objects to
create? (Seems like under such situation is there no other choice but using
"new")

You know, i always tell myself not that i should avoid using new, but
that i should avoid using delete. i know that sounds flip, but i swear
by "smart" pointers of varying degrees of "smart"ness.

auto_ptr<Foo> bar1(new Foo());
//...
//no delete

boost::scoped_ptr<Foo> bar2(new Foo());
//...
//no delete

boost::shared_ptr<Foo> bar3(new Foo());
//...
//no delete

//and my own
dynamic_obj<Foo> bar4(new Foo());
//...
//on copy it allocates then copies
//...
//no delete

mark
 
M

Mark A. Gibbs

Andrew said:
What does std::allocator not do that you want?

Anything useful. For what peeves me specifically, see 20.1.5 p4 & p5.

Also, the lack of some kind of standardized auto_allocator to complement
auto_ptr using a specific allocator is annoying some days. It would
really have been nice to have some version of new/delete that takes an
allocator type and instance in some kind of policy. These are just a few
geek fantasies i entertain when i'm retyping boilerplate.

mark
 
T

tom_usenet

What does std::allocator not do that you want?

Apart from in-place expansion of memory (a la realloc)?

Well, it's lower level than what I'm suggesting, which fits in
somewhere between std::allocator and std::vector. It won't have a
capacity, but it will be copyable and exception safe. Alexandrescu
wrote about some kind of buffer class which is more what I'm thinking
of.
http://www.cuj.com/documents/s=7992/cujcexp1908alexandr/alexandr.htm

Tom
 

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

Members online

Forum statistics

Threads
474,169
Messages
2,570,917
Members
47,458
Latest member
Chris#

Latest Threads

Top