Re: Same name parameter and data member initialization
James Kanze wrote:
So allocate it:
,name( new char[ strlen(name) + 1 ] )
Or better yet:
,name( duplicateString(name) )
with the necessary functionality in duplicateString.
Note, the code is unsafe for exceptions (in generic case). With the
kind of pointers you need ideally two-stage sequence of initializing:
A::A(int id, double pay, char* name ): // auto: //:)
id(id),
pay(pay),
//first stage
//here zero for delete[] safe
name(0)
{
//second stage
A::name=new char[ strlen(name) + 1 ];
}
but since C++ does not support control of auto/noauto destructor
calls, you can do like this:
//dtor replacement
A::do_delete(){ delete[] name; }
//dtor
A::~A(){ do_delete(); }
//will call dtor
A& A::operator= (const A&);
//will call dtor replacement
A::A(int id, double pay, char* name ):
id(id),
pay(pay),
//first stage
//here zero for delete[] safe
name(0)
{
try{
//second stage
A::name=new char[ strlen(name) + 1 ];
...
}
catch(...){ do_delete(); throw; }
}
Appropriate RAII wrapper instead of POD pointers is safe for
exceptions for current-style code.
POD pointers as member of class can be found, for example, while
porting old-style code without exceptions into old-style code with.
You probably can use (or write) a wrapper to replace POD pointer
behaviour for the kind of code instead of two-stage initializing (to
do porting old-style code without exceptions into new-style code
with).
Once I have refused from any of the porting because of not-stacked C++
exceptions:
class A
{
Internal a,b;
~A()
{
//can throw during throw
Closer closer(::external,a,b);
closer.do();
}
};
The possible runtime error here is very hard to detect at compile
time, because "Closer" is general-purpose class - is not developed to
be used for destructors only and whole code has not been written for
"no any destructors for non-wrapper class" paradigm :)
Maksim A. Polyanin
http://grizlyk1.narod.ru/cpp_new