[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.c++

Create class using new?

mlt

11/21/2008 7:30:00 PM

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?

10 Answers

Tonni Tielens

11/21/2008 8:02:00 PM

0

On Nov 21, 8:29 pm, "mlt" <a...@asd.com> wrote:
> 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.

acehreli

11/21/2008 8:41:00 PM

0

On Nov 21, 12:01 pm, Tonni Tielens <tonnitiel...@gmail.com> wrote:
> On Nov 21, 8:29 pm, "mlt" <a...@asd.com> 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

Salt_Peter

11/21/2008 8:44:00 PM

0

On Nov 21, 2:29 pm, "mlt" <a...@asd.com> wrote:
> 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.

mlt

11/21/2008 8:46:00 PM

0


<acehreli@gmail.com> wrote in message
news:0042c6ae-fde7-42f2-912c-f7ba4f7b5105@w1g2000prk.googlegroups.com...
On Nov 21, 12:01 pm, Tonni Tielens <tonnitiel...@gmail.com> wrote:
> On Nov 21, 8:29 pm, "mlt" <a...@asd.com> 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?

acehreli

11/21/2008 9:18:00 PM

0

On Nov 21, 12:46 pm, "mlt" <a...@asd.com> wrote:
> 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

Paavo Helde

11/21/2008 9:53:00 PM

0

"mlt" <asdf@asd.com> kirjutas:

> 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?).

1) defines a default-constucted variable t of type Test.

2) declares a function t(), taking no arguments and returning a Test
object by value (welcome to the wonderful world of C++ cryptic
declaration syntax!).

>
> I can't do:
>
> Test t = new Test();

You probably want

Test* t = new Test();

In C++, the types Test* (a pointer) and Test (a class) are different.

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.

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

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.

hth
Paavo

James Kanze

11/22/2008 10:49:00 AM

0

On Nov 21, 9:44 pm, Salt_Peter <pj_h...@yahoo.com> wrote:
> On Nov 21, 2:29 pm, "mlt" <a...@asd.com> wrote:

[...]
> > 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.

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.

--
James Kanze (GABI Software) email:james.kanze@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

James Kanze

11/22/2008 10:58:00 AM

0

On Nov 21, 10:52 pm, Paavo Helde <pa...@nospam.please.org> wrote:
> "mlt" <a...@asd.com> kirjutas:

[...]
> 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.)

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

> 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.

--
James Kanze (GABI Software) email:james.kanze@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

zxcv

3/25/2010 2:06:00 PM

0

On Mar 24, 1:35 pm, "Joe User" <joeu2004> wrote:
> "zxcv" <zxcvnos...@yahoo.com> wrote:
>
> On Mar 24, 12:31 pm, "Joe User" <joeu2004> wrote:
>
> > > Try:
> > > If Round(inval,2) = inval Then
> [....]
> > Thanks for the input but I need to do this in VBA
> > as I have no control over the input and cannot put
> > any formulas in the sheet.  Someone else enters the
> > data and then another person hits a button that I
> > created.
>
> I don't understand your comment.  What I wrote is for VBA, and it is
> intended to deal with exactly the situation that you describe.  I think you
> misunderstand my comments.  Perhaps you should just give it a try.
>
> PS:  Sorry, I wrote "=" where you wanted "<>".  That's a simple change, heh?
>
> ----- original message -----
>
> "zxcv" <zxcvnos...@yahoo.com> wrote in message
>
> news:6d74dc36-1fae-4269-8bba-dd366ae0b776@g28g2000yqh.googlegroups.com...
> On Mar 24, 12:31 pm, "Joe User" <joeu2004> wrote:
>
>
>
> > "zxcv" <zxcvnos...@yahoo.com> wrote:
> > > I need to do some input validation so to check if a
> > > value has no more than 2 decimal digits. So 14.12
> > > is valid but 14.123 is not.
>
> > Try:
>
> > If Round(inval,2) = inval Then
>
> > Normally, I would opt for WorksheetFunction.Round or even
> > Evaluate("round(...)") instead of the VB Round function. There are
> > functional differences. In this case, I do not think it makes a
> > difference.
> > Nevertheless, you might want to use one of those alternatives instead,
> > just
> > to be sure.
>
> > ----- original message -----
>
> > "zxcv" <zxcvnos...@yahoo.com> wrote in message
>
> >news:3466ddcc-9050-4873-9377-bcaee5b6517e@z3g2000yqz.googlegroups.com...
>
> > >I need to do some input validation so to check if a value has no more
> > > than 2 decimal digits. So 14.12 is valid but 14.123 is not.
>
> > > I have tried doing a check like this:
>
> > > If Int(inval * 100) <> inval * 100 Then
>
> > > but this gets a rounding error with certain values like 2.22. If I
> > > subtract one side above from the other I get a difference on the order
> > > of 10^-21.
>
> > > So I tried rounding the numbers to do a test like this:
>
> > > If Round(Int(inval * 100), 10) <> Round(inval * 100, 10) Then
>
> > > and this does something weird like rounding Round(Int(0.29 * 100), 10)
> > > to 28.
>
> > > Is there some simpler way to check that a number does not have too
> > > many decimal digits?
>
> Thanks for the input but I need to do this in VBA as I have no control
> over the input and cannot put any formulas in the sheet.  Someone else
> enters the data and then another person hits a button that I created.

I see! I did not know that the WorksheetFunction object existed. I
will make use of this more in the future.

Thank you.

zxcv

3/25/2010 2:06:00 PM

0

On Mar 24, 1:30 pm, "Joe User" <joeu2004> wrote:
> Embellishment....
>
> "zxcv" <zxcvnos...@yahoo.com> wrote:
> > I tried rounding the numbers to do a test like this:
> > If Int(inval * 100) <> inval * 100 Then
>
> > but this gets a rounding error with certain values like 2.22.
>
> The reason that does not work is because most numbers with decimal fractions
> cannot be represented exactly.  Instead, they are represented by a sum of 53
> consecutive powers of two (bits), for example 2*2^1 + 0*2^0 + 0*2^-1 +
> 0*2^-2 + 1*2^-3 + etc.
>
> Consequently, 2.22 is represented by exactly
> 2.22000000000000,0195399252334027551114559173583984375.  Int(2.22*100) is
> exactly 222.  But 2.22*100 is
> 222.000000000000,028421709430404007434844970703125, preserving the
> additional bits used to approximate 0.22 in this context.
>
> In contrast, Round(inval,2) results in inval exactly as it would be
> represented internally if it were entered with 2 decimal places.  So if
> inval is 2.22, Round(inval,2) results in
> 2.22000000000000,0195399252334027551114559173583984375.  But if inval were
> 2.22+2^-51 (the smallest value larger than 2.22), it would be represented
> internally as 2.22000000000000,06394884621840901672840118408203125, and
> Round(inval,2) does not equal inval.
>
> Note:  You cannot enter the
> 2.2200000000000006394884621840901672840118408203125 as a constant in Excel;
> however, it can be the result of a calculation.  Also, you can enter that
> constant in VBA, including as input to an InputBox.  Caveat:  If you write
> that constant in a VBA statement, the VBA editor might change it later when
> you edit the line.  It would be more reliable to write
> Cdbl("2.2200000000000006394884621840901672840118408203125").
>
> ----- original message -----
>
> "Joe User" <joeu2004> wrote in message
>
> news:%233Lsx92yKHA.5036@TK2MSFTNGP02.phx.gbl...
>
> > "zxcv" <zxcvnos...@yahoo.com> wrote:
> >> I need to do some input validation so to check if a
> >> value has no more than 2 decimal digits.  So 14.12
> >> is valid but 14.123 is not.
>
> > Try:
>
> > If Round(inval,2) = inval Then
>
> > Normally, I would opt for WorksheetFunction.Round or even
> > Evaluate("round(...)") instead of the VB Round function.  There are
> > functional differences.  In this case, I do not think it makes a
> > difference. Nevertheless, you might want to use one of those alternatives
> > instead, just to be sure.
>
> > ----- original message -----
>
> > "zxcv" <zxcvnos...@yahoo.com> wrote in message
> >news:3466ddcc-9050-4873-9377-bcaee5b6517e@z3g2000yqz.googlegroups.com...
> >>I need to do some input validation so to check if a value has no more
> >> than 2 decimal digits.  So 14.12 is valid but 14.123 is not.
>
> >> I have tried doing a check like this:
>
> >>     If Int(inval * 100) <> inval * 100 Then
>
> >> but this gets a rounding error with certain values like 2.22.  If I
> >> subtract one side above from the other I get a difference on the order
> >> of 10^-21.
>
> >> So I tried rounding the numbers to do a test like this:
>
> >>     If Round(Int(inval * 100), 10) <> Round(inval * 100, 10) Then
>
> >> and this does something weird like rounding Round(Int(0.29 * 100), 10)
> >> to 28.
>
> >> Is there some simpler way to check that a number does not have too
> >> many decimal digits?

Thanks. That is a great bit of information. I never knew why the
rounding errors happened.