Style (or otherwise?) question: creating temporary to invoke function

D

Denis Remezov

jeffc said:
Let's say you're in some function , and you want to accomplish some task x
that is provided for you by a class, A.
Which of these do you prefer, and is there a technical reason for it? (This
is actually the sort of thing that might be
provided for with a static class function, but one is not provided in this
case - an instance must be created.)

void f()
{
A a;
a.x();

A* p = new A();
p->x();
delete p;

A().x();
}


Normally, A().x(); No superfluous names. It is different from A a1; a1.x();
in that that the lifetime of a1 lasts until the end of the block; in the first
case, the object can (or shall? correct me on this if I'm wrong) be destructed
as soon as x(); returns. Which is something to keep in mind but normally should
be considered a bonus.

If there are reasons against A().x(); (style, maintainability, or
when the object must exist until the end of the block (e.g. we obtain and use
parts of it; I'm not delving into morality of that and the reasons why)), then
A a;
a.x();

Almost never this one:
A* p = new A();
p->x();
delete p;

which is longer to type, prone to misuse, typically less efficient and,
unless x() never throws, simply wrong.

[OT] I might consider the latter (corrected for the exception bug) if A
is extremely large and can cause problems with the stack reallocation
mechanism on a specific OS with a specific compiler, but this is exotic,
dubious and off-topic. [/OT]

Denis
 
J

jeffc

Let's say you're in some function , and you want to accomplish some task x
that is provided for you by a class, A.
Which of these do you prefer, and is there a technical reason for it? (This
is actually the sort of thing that might be
provided for with a static class function, but one is not provided in this
case - an instance must be created.)

void f()
{
A a;
a.x();

A* p = new A();
p->x();
delete p;

A().x();
}
 
E

E. Robert Tisdale

jeffc said:
Let's say you're in some function and you want to accomplish
some task x that is provided for you by a class, A.
Which of these do you prefer, and is there a technical reason for it?
(This is actually the sort of thing that might be provided for
with a static class function,
but one is not provided in this case - an instance must be created.)


void f(void) {
A a;
a.x(); // OK

A* p = new A();
p->x();
delete p; // Never!

A().x(); // Best
}

Leaving a reference lying around
to an object that should never be reference again
is an invitation for trouble.
If some other programmer (meaning you after a while) maintaining f()
doesn't realize that the object to which p points has been deleted
and decides to add code to modify the object through p,
The function may or may not exhibit the expected behavior
and the bug may be very difficult to detect and fix.
 
I

Ian

jeffc said:
Let's say you're in some function , and you want to accomplish some task x
that is provided for you by a class, A.
Which of these do you prefer, and is there a technical reason for it? (This
is actually the sort of thing that might be
provided for with a static class function, but one is not provided in this
case - an instance must be created.)

void f()
{
A a;
a.x();
Fine, a on stack.
A* p = new A();
p->x();
delete p;
Has to call new and allocate p from heap, OTT.

Fine and concise!

Ian
 
I

Ioannis Vranos

jeffc said:
Let's say you're in some function , and you want to accomplish some task x
that is provided for you by a class, A.
Which of these do you prefer, and is there a technical reason for it? (This
is actually the sort of thing that might be
provided for with a static class function, but one is not provided in this
case - an instance must be created.)

void f()
{
A a;
a.x();

A* p = new A();
p->x();
delete p;


Do the second if for some reason you can't do the first.




Do this paranoid stuff if for some reason you cannot do the previous two.






Ioannis Vranos
 
K

Kevin Goodsell

jeffc said:
Let's say you're in some function , and you want to accomplish some task x
that is provided for you by a class, A.
Which of these do you prefer, and is there a technical reason for it? (This
is actually the sort of thing that might be
provided for with a static class function, but one is not provided in this
case - an instance must be created.)

void f()
{
A a;
a.x();

A* p = new A();
p->x();
delete p;

A().x();
}

If I wanted to do something like this, I imagine I'd ask myself, "Should
A::x() be static?"

-Kevin
 
J

jeffc

Ioannis Vranos said:
Do the second if for some reason you can't do the first.


Do this paranoid stuff if for some reason you cannot do the previous two.

There was nothing paranoid about it - merely succinctness. Which is not to
say I prefer succinctness over clarity. In fact, in the specific situation
I'm looking at, there is a parameter list that's long (3 very long parameter
names) so that the statement will span multiple lines. Therefore I don't
think I'll use the last technique, because I think the actual function call
(which is an extremely short name) will get lost in the soup.
 
A

Andrey Tarasevich

jeffc said:
Let's say you're in some function , and you want to accomplish some task x
that is provided for you by a class, A.
Which of these do you prefer, and is there a technical reason for it? (This
is actually the sort of thing that might be
provided for with a static class function, but one is not provided in this
case - an instance must be created.)

void f()
{
A a;
a.x();

A* p = new A();
p->x();
delete p;

A().x();
}

If class 'A' doesn't have any internal state or you don't care about
that state, then

A().x();

is the best way to do it. Otherwise, use

A a;
a.x();
 
I

Ioannis Vranos

jeffc said:
task two.

There was nothing paranoid about it - merely succinctness.



I did not mean to insult you, i spoke a bit freely. Let me rephrase: Do this
temporary object stuff ...

Which is not to
say I prefer succinctness over clarity. In fact, in the specific situation
I'm looking at, there is a parameter list that's long (3 very long parameter
names) so that the statement will span multiple lines. Therefore I don't
think I'll use the last technique, because I think the actual function call
(which is an extremely short name) will get lost in the soup.


Well if the long function names bother you, you can do friend functions in
the style:


inline whatever_the_method_returns function1(A &x, whatever_parameter y)
{
return x.the_long_version_member_function(y);
}


// ...

A a;

function1(a, y);


Of course there are millions of things you can do like,

class capsule: public A
{
public:
// Your new short-name versions of functions accessing the old ones
// with *this
};


or


class capsule
{

public:
int some_func()
{
A a;

return a.x();
}
};

or

class capsule
{
A a;
// A *a;

public:
int some_func() { // ... }
// ...
};


// ...






Ioannis Vranos
 
A

Andrey Tarasevich

Kevin said:
...
If I wanted to do something like this, I imagine I'd ask myself, "Should
A::x() be static?"
...

Yes, by of 'x' happens to be 'operator ()' then you are out of luck,
since 'operator ()' cannot be static.
 
I

Ioannis Vranos

Ioannis Vranos said:
Well if the long function names bother you, you can do friend functions in
the style:


Make the above:

"Well if the long function names bother you, you can do small conversion
functions in the style:"






Ioannis Vranos
 
I

Ioannis Vranos

With two errata fixed. :)



Well if the long function names bother you, you can do small conversion
functions in
the style:


inline whatever_the_method_returns function1(A &x, whatever_parameter y)
{
return x.the_long_version_member_function(y);
}


// ...

A a;

function1(a, y);


Of course there are millions of things you can do like,

class capsule: public A
{
public:
// Your new short-name versions of functions accessing the old ones
};


or


class capsule
{

public:
int some_func()
{
A a;

return a.x();
}
};

or

class capsule
{
A a;
// A *a;

public:
int some_func() { // ... }
// ...
};


// ...






Ioannis Vranos
 
K

Kevin Goodsell

jeffc said:
You didn't read carefully :)

No, no, you're confused. See, in the book it only says that the shadow
around the Balrog resembled wings, it never says that it actually had
wings. Jackson messed up.

Wait, what?

:p

-Kevin
 
J

jeffc

Ioannis Vranos said:
I did not mean to insult you, i spoke a bit freely. Let me rephrase: Do this
temporary object stuff ...

No problem.
Well if the long function names bother you, you can do friend functions in
the style:

I should have been more clear that I'm maintaining some code - I have no
control over the class A - I only can write client code in the style I
choose.
 
J

jeffc

Kevin Goodsell said:
No, no, you're confused. See, in the book it only says that the shadow
around the Balrog resembled wings, it never says that it actually had
wings. Jackson messed up.

:)
 
I

Ioannis Vranos

jeffc said:
I should have been more clear that I'm maintaining some code - I have no
control over the class A - I only can write client code in the style I
choose.

The friend functions i said was a mistake. I meant to say small functions.
Although you may have not access in the source you can do all the stuff i
mentioned except of the inheritance one if inheritance is not permitted for
the specific type in the specific platform.






Ioannis Vranos
 
D

David Harmon

On Sat, 17 Apr 2004 00:19:50 +0300 in comp.lang.c++, "Ioannis Vranos"
Do the second if for some reason you can't do the first.

You would never allocate with 'new' for such a thing where you don't
even care about personally controlling the lifetime of the object. It
belongs only on the stack.

And if for some reason it needed to be allocated with 'new', that would
still be wrong. If x() throws an exception, the allocated object is
leaked. Horrors! If you must go this route, the minimum acceptable is

Do this paranoid stuff if for some reason you cannot do the previous two.

This one is simplest and most correct. Do not multiply entities
unnecessarily. Hah, I'll show you paranoid. Memory leaks are evil.
 

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

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,581
Members
45,056
Latest member
GlycogenSupporthealth

Latest Threads

Top