Default Pamameter

  • Thread starter Massimiliano Alberti
  • Start date
M

Massimiliano Alberti

Now... I have this piece of code: the function DoSomething has a parameter,
but it can be called without it... If it's called without it, it will build
an object of the right type and use it. No use of new/delete! (I need it to
be FAST). No unnecessary building of the object CMyOb when it's not needed
(perhaps it has a very very slow constructor).. I know the compiler will
probably inline DoSomething and it won't exist in the compiled program.

inline void DoSomething(CMyOb *pmyob = NULL)
{
if (pmyob)
_DoSomething(pmyob);
else {
CMyOb myob;
_DoSomething(&myob);
}

void _DoSomething(CMyOb *pmyob)
{
}

The question... Can I do something like (I want better readability of the
source):
inline void DoSomething(CMyOb *pmyob = &CyOb())
{
}

what is the scope of the created CMyOb? Is it created on the stack?

And now the 2nd question... If it's possible to do it, how can I do this:
inline void DoSomething(CMyOb *pmyob = NULL)
{
if (pmyob)
_DoSomething(pmyob);
else {
CMyOb myob;
FillObject(&myob);
_DoSomething(&myob);
}

(the object need to be filled with special data that the constructor of the
object can't know. I can build the FillObject function however I want)

--- thanks
 
J

Janusz Szpilewski

Massimiliano said:
The question... Can I do something like (I want better readability of the
source):
inline void DoSomething(CMyOb *pmyob = &CyOb())
{
}
what is the scope of the created CMyOb? Is it created on the stack?


Such a construction is invalid. You cannot take address of a temporary.
However the idea is realizable just use references instead:

inline void DoSomething2(const CMyOb& pmyob = CMyOb())

This is perfectly legal and the lifetime of the temporary object will be
as long as that of the reference to which it is assigned. Of course
temporaries are created on the stack. However you cannot modify a
temporary object so if your code must do it this solution is not
applicable to your problem.


And now the 2nd question... If it's possible to do it, how can I do this:
inline void DoSomething(CMyOb *pmyob = NULL)
{
if (pmyob)
_DoSomething(pmyob);
else {
CMyOb myob;
FillObject(&myob);
_DoSomething(&myob);
}

(the object need to be filled with special data that the constructor of the
object can't know. I can build the FillObject function however I want)

Maybe there is a typo (missing 'not') however I do not see how you could
combine both solutions. You may consider adding a flag to CMyOb
indicating if it was filled, or create a factory function encapsulating
creating and filling of the object.


Regards,
Janusz
 
R

Rob Williscroft

Massimiliano Alberti wrote in
Now... I have this piece of code: the function DoSomething has a
parameter, but it can be called without it... If it's called without
it, it will build an object of the right type and use it. No use of
new/delete! (I need it to be FAST). No unnecessary building of the
object CMyOb when it's not needed (perhaps it has a very very slow
constructor).. I know the compiler will probably inline DoSomething
and it won't exist in the compiled program.

inline void DoSomething(CMyOb *pmyob = NULL)
{
if (pmyob)
_DoSomething(pmyob);
else {
CMyOb myob;
_DoSomething(&myob);
}

identifiers with a leading underscore followed by an Uppercase letter
are reserved for use by the compile/standard library implemetor, you
shoudn't use them.
void _DoSomething(CMyOb *pmyob)
{
}

The question... Can I do something like (I want better readability of
the source):
inline void DoSomething(CMyOb *pmyob = &CyOb())
{
}

There is really no need to do this (and no you cant do it (*)),
overloading will help:

void DoSomething( CMyOb &ob )
{
// whatever
}

inline void DoSomething()
{
CMyOb ob = FillObject();
DoSomeThing( ob );
}

Note (*) actually you might, but only if you've provided CMyOB with
a member operator & () (a *very* Bad Thing(tm)).
what is the scope of the created CMyOb? Is it created on the stack?

Yes.

And now the 2nd question... If it's possible to do it, how can I do
this: inline void DoSomething(CMyOb *pmyob = NULL)
{
if (pmyob)
_DoSomething(pmyob);
else {
CMyOb myob;
FillObject(&myob);
_DoSomething(&myob);
}

(the object need to be filled with special data that the constructor
of the object can't know. I can build the FillObject function however
I want)

The dodgy _DoSomething name aside there is nothing wrong with the above.
However you might want to change FillObject() to return a CMyOb by value:

CMyOB FillObject()
{
//either:

CMyOb ob;
//whatever
return ob;

//or
//whatever
return CMyOb( /* paramiters calculated by "whatever" */ );
}

With a sutibly compliant compiler calling the above like:

CMyOb ob = FillObject();

Will bypass 1 constructor call, this is called RVO (Return Value
Optimisation). The first form (after //either:) is less widely
implemented than the second, so use the second form if you can.

HTH.

Rob.
 

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,161
Messages
2,570,892
Members
47,430
Latest member
7dog123

Latest Threads

Top