Create class using new?

M

mlt

I have the following class:

class Test {

public:
Test() {
a = 33;
}

private:
int a;
};


When I want to create an instance of this class in eg java I do:

Test t = new Test();

but in C++ I either do:

1) Test t;
or
2) Test t();

(what are the difference between 1 and 2?).

I can't do:

Test t = new Test();

but is that not the only way to make sure the instance lives after the
calling function has returned?
 
T

Tonni Tielens

but is that not the only way to make sure the instance lives after the
calling function has returned?

Option 1 and 2 are equal. If a class has a default constructor the ()
behind the identifier can be omitted. In C++ you can also do

Test* t = new Test();

The difference with your options is that in this case a Test object is
dynamically created and t is a Test pointer that points to that
object. This is indeed the only way to make sure the instance lives
after the function returned, but keep in mind that in C++ dynamically
created objects are not freed automatically. You will have to
explicitly call delete on a pointer to the object. Eg.

Test* t = new Test();
// Some code.
delete t;

If you don't, the object t points to will never be deleted and you
have a memory leak. I suggest you to read a good book on C++ if these
things are unfamiliar to you.
 
S

Salt_Peter

I have the following class:

class Test {

public:
Test() {
a = 33;
}

private:
int a;

};

When I want to create an instance of this class in eg java I do:

Test t = new Test();

but in C++ I either do:

1) Test t;
or
2) Test t();

(what are the difference between 1 and 2?).

I can't do:

Test t = new Test();

new returns a pointer, since t is an instance of Test, you can't store
a pointer (to an allocated Test) into it, thankfully. This works:

Test* p_t = new Test();
....
delete p_t; // required

It is unwise to allocate on the heap unless absolutely necessary. And
when it is necessary its better to rely on RAII or smart pointers.
So this is better since it will allocate + invoke ctor + get
destructed automatically.

Test t; // allocated on the stack, not heap
but is that not the only way to make sure the instance lives after the
calling function has returned?

No, definitely not the way. Its shoddy programming to allocate
something over there and deallocate somewhere else. Managing the
lifetime of an object should either be automatic or given to a single
manager. In Java, your GC takes care of that while C++ uses a
different discipline. Java only uses the stack to store primitives, C+
+ can use the stack to store anything.
 
M

mlt

On Nov 21, 8:29 pm, "mlt" <[email protected]> wrote:

The options were

1) Test t;
or
2) Test t();
Option 1 and 2 are equal.

That never fails to catch us off guard: Option 2 is the declaration of
a function. :)

Ali



Ok so:

Test t();

actually declares a function that returns a type Test, which could be
implemented/defined in e.g a .cpp file? But what about:


Test* t = new Test();

versus:

Test* t = new Test;

that would create the same pointer right?
 
A

acehreli

But what about:

Test* t = new Test();

versus:

Test* t = new Test;

that would create the same pointer right?

The short answer is: yes, in both cases, t points to an object
allocated on the heap.

But there will be a difference whether Test is a POD or not. The rules
are too complicated for me to remember. I need to do a search
everytime I wonder the behavior.

In this case, if Test is non-POD, the two are the same and the object
is default constructed. But if Test is a POD, then the second will not
"zero-initialize" the object.

A search for "is there a difference between new MyClass; and new
MyClass()" in this group finds a thread about the same issue with many
more responses.

Ali
 
J

James Kanze

On Nov 21, 2:29 pm, "mlt" <[email protected]> wrote:

[...]
No, definitely not the way. Its shoddy programming to allocate
something over there and deallocate somewhere else.

That is, of course, quite simply false. Unless you have a need
to create an object in one place, and destroy it elsewhere,
there's no point in using dynamic allocation. (There are
exceptions, but this is doubtlessly the major use of dynamic
allocation in application level code.)
Managing the lifetime of an object should either be automatic
or given to a single manager.

Not really. If you're object really has significant behavior,
it often makes the most sense that it manage it's own lifetime,
once created. In a server, most long lived objects will be
destructed in a transaction manager, during the commit phase;
it's not the transaction manager which creates them. (The
transaction manager does take over to a certain degree rapidly
after creation, but it's not the same instance as the one which
destructs them, unless rollback occurs.) GUI objects may follow
the self-destruct pattern, but often, they will be destroyed by
the owning object, i.e. client code creates the object, then
inserts it into a panel in a window; destruction is ensured by
the panel, when it is destroyed, or possibly it is the
responsibility of whoever removes the object from its containing
element.

Most of the time, if you could use some simple manager, you
shouldn't be using dynamic allocation to begin with.
In Java, your GC takes care of that while C++ uses a different
discipline.

Yes and no. Garbage collection doesn't dispose of a window, or
remove it from a panel; in general, garbage collection only
kicks in once the programmer has decided that the object is no
longer needed. (There are exceptions, of course, and they're
frequent enough to make garbage collection useful in C++ as
well. But they don't dominate.)
Java only uses the stack to store primitives, C++ can use the
stack to store anything.

More to the point, in C++, objects are copiable and assignable
(unless you forbid it---which you should for any object which
has identity). And you would generally never allocate a
copiable or an assignable object dynamically.
 
J

James Kanze


[...]
However, a raw pointer is usually not a good way to manage the
ownership of the created object, it may get lost too easily in
presence of exceptions, and there is no garbage collection
present by default. A better way might be to use std::auto_ptr
or boost::shared_ptr.

Or registering the object somewhere so that it can be found as
needed. std::auto_ptr is very useful locally, I find, to hold
the pointer between the moment you've created the object, and
the moment it has effectively been handed over; one rule or
design pattern might be to always put the results of new
immediately into an auto_ptr, on which you call release once the
object is "established" or "published", i.e. once it has been
registered where it will be known and found in the future.

I've found much less use for shared_ptr; with the default
destroy object, mainly only to simulate garbage collection (and
in that role, it doesn't work as well as garbage collection, by
far); for larger, more complex objects, it's downright
dangerous. (On the other hand, with a custom destroyer, it's
very useful for managing non-object based resources, like
locks or even program coherence.)
Instances are needed only for "entity" objects. For "value"
objects it is normal to return them by value from functions,
just like int. BTW, even C allows returning structs by value.

Yes, but he's coming from Java:). In well written Java, value
objects are final and have no mutating functions (see
java.lang.String). Regretfully, well written Java seems even
rarer than well written C++, and because the language doesn't
encourage it, many Java programmers fail to make the
distinction.

The important aspect here, of course, is that C++ allows the
programmer to define the copy semantics (copy constructor,
assignment operator) of his object, so you can use values really
effectively.
 

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,431
Messages
2,571,679
Members
48,796
Latest member
Greg L.

Latest Threads

Top