Object construction question

B

Bart Simpson

I have the ff class decl:

class ArrayData : public myArray
{
public:
inline ArrayData(){ InitArray(&m_arr);}
inline explicit ArrayData(const std::string& name):m_name(name){
InitArray(&m_arr);}
inline explicit ArrayData(const ArrayData& arr):m_name(arr.m_name) {
CopyArray(&arr.m_arr, &m_arr) ;}
inline ArrayData& operator= (const ArrayData& rhs)
{
if (this != &rhs){ CopyArray(&rhs.m_arr, &m_arr) ; m_name = rhs.m_name ;}
return *this ;
}
inline ~ArrayData(){ FreeArray(&m_arr); }
inline const std::string& Name() const { return m_name ; }

private:
tpArray m_arr ;
std::string m_name ;
};


I also have a template class called PointerList<T>, which allows me to
manage a list of pointers generically. I made the copy/assignment ctors
for PointerList private.


I have a class (A) that uses a list of pointers of type ArrayData. I
need to implement a copy constructor for class A, and that requires a
member by member copy of the elements in the list...

I implemented this:

......
//Copy PointerList<ArrayData> items element by element
if (!rhs.m_outarray_1ist.empty())
{
PointerList<ArrayData>::const_iterator cit = rhs.m_outarray_1ist.begin();
for (cit; cit != rhs.m_outarray_1ist.end(); cit++)
{
ArrayData *arr = new ArrayData(*cit); //Barfs here
m_outarray_1ist.push_back(arr) ;
}
}


However the compiler barfs at the line where the variable is being
created, with the error message:

cannot convert parameter 1 from 'ArrayData *const ' to 'const std::string &'

class ArrayData has a copy constructor that accepts a const ArrayData&,
so why does the compiler insist on casting it to a std::string (even
though I am using the 'explicit' keyword ?
 
F

Fei Liu

Bart said:
I have the ff class decl:

class ArrayData : public myArray
{
public:
inline ArrayData(){ InitArray(&m_arr);}
inline explicit ArrayData(const std::string& name):m_name(name){
InitArray(&m_arr);}
inline explicit ArrayData(const ArrayData& arr):m_name(arr.m_name) {
CopyArray(&arr.m_arr, &m_arr) ;}
inline ArrayData& operator= (const ArrayData& rhs)
{
if (this != &rhs){ CopyArray(&rhs.m_arr, &m_arr) ; m_name =
rhs.m_name ;}
return *this ;
}
inline ~ArrayData(){ FreeArray(&m_arr); }
inline const std::string& Name() const { return m_name ; }

private:
tpArray m_arr ;
std::string m_name ;
};


I also have a template class called PointerList<T>, which allows me to
manage a list of pointers generically. I made the copy/assignment ctors
for PointerList private.


I have a class (A) that uses a list of pointers of type ArrayData. I
need to implement a copy constructor for class A, and that requires a
member by member copy of the elements in the list...

I implemented this:

.....
//Copy PointerList<ArrayData> items element by element
if (!rhs.m_outarray_1ist.empty())
{
PointerList<ArrayData>::const_iterator cit =
rhs.m_outarray_1ist.begin();
for (cit; cit != rhs.m_outarray_1ist.end(); cit++)
{
ArrayData *arr = new ArrayData(*cit); //Barfs here
m_outarray_1ist.push_back(arr) ;
}
}


However the compiler barfs at the line where the variable is being
created, with the error message:

cannot convert parameter 1 from 'ArrayData *const ' to 'const
std::string &'

class ArrayData has a copy constructor that accepts a const ArrayData&,
so why does the compiler insist on casting it to a std::string (even
though I am using the 'explicit' keyword ?

What's the prototype of your PointerList<>::const_iterator? The compiler
is complaining that it cannot convert
*PointerList<ArrayData>::const_iterator to const std::string &

If const_iterator is simply a typedef T * const const_iterator, then it
all makes sense.

Fei
 
Z

Zeppe

Bart said:
However the compiler barfs at the line where the variable is being
created, with the error message:

cannot convert parameter 1 from 'ArrayData *const ' to 'const
std::string &'

class ArrayData has a copy constructor that accepts a const ArrayData&,
so why does the compiler insist on casting it to a std::string (even
though I am using the 'explicit' keyword ?

Beacuse, as the compiler tells you, you are giving to the constructor a
ArrayData* const, not a const ArrayData&. Dereference two times:

ArrayData *arr = new ArrayData(**cit);


Regards,

Zeppe
 
S

Salt_Peter

I have the ff class decl:

class ArrayData : public myArray
{
public:
inline ArrayData(){ InitArray(&m_arr);}
inline explicit ArrayData(const std::string& name):m_name(name){
InitArray(&m_arr);}
inline explicit ArrayData(const ArrayData& arr):m_name(arr.m_name) {
CopyArray(&arr.m_arr, &m_arr) ;}
inline ArrayData& operator= (const ArrayData& rhs)
{
if (this != &rhs){ CopyArray(&rhs.m_arr, &m_arr) ; m_name = rhs.m_name ;}
return *this ;
}
inline ~ArrayData(){ FreeArray(&m_arr); }
inline const std::string& Name() const { return m_name ; }

private:
tpArray m_arr ;
std::string m_name ;

};

I also have a template class called PointerList<T>, which allows me to
manage a list of pointers generically. I made the copy/assignment ctors
for PointerList private.

I have a class (A) that uses a list of pointers of type ArrayData. I
need to implement a copy constructor for class A, and that requires a
member by member copy of the elements in the list...

I implemented this:

.....
//Copy PointerList<ArrayData> items element by element
if (!rhs.m_outarray_1ist.empty())
{
PointerList<ArrayData>::const_iterator cit = rhs.m_outarray_1ist.begin();
for (cit; cit != rhs.m_outarray_1ist.end(); cit++)
{
ArrayData *arr = new ArrayData(*cit); //Barfs here
m_outarray_1ist.push_back(arr) ;

Since the code shown is incomplete and since PointerList< ArrayData >,
instead of PointerList< ArrayData* >, is shown here, is
rhs.m_outarray_1ist.begin() returning an iterator to a pointer or an
iterator to an ArrayData element?

According to the error shown - its a pointer thats delivered by *cit
above (thats rather peculiar). Before you go "ahh, i get it -
dereference the dereferenced iterator is the solution" consider the
poor programmer who has to delve into this mess.

wild guess:
m_outarray_1ist.push_back( *cit ) ;

Then we'll start disscussing transfer of ownership here cause i see
lots of new's but no deletes.
At which point i'ld strongly suggest boost:shared_ptr.
}

}

However the compiler barfs at the line where the variable is being
created, with the error message:

cannot convert parameter 1 from 'ArrayData *const ' to 'const std::string &'

class ArrayData has a copy constructor that accepts a const ArrayData&,
so why does the compiler insist on casting it to a std::string (even
though I am using the 'explicit' keyword ?

ArrayData* const is a const pointer - what do you mean by 'casting'?
read the error: The compiler sees only one conversion ctor:
ArrayData(const std::string& name);
and it doesn't fit the bill.
 
B

Bart Simpson

Zeppe said:
Bart Simpson wrote:




Beacuse, as the compiler tells you, you are giving to the constructor a
ArrayData* const, not a const ArrayData&. Dereference two times:

ArrayData *arr = new ArrayData(**cit);


Regards,

Zeppe

Dereferencing the variable (cit) twice fixed the problem. I understand
why I need the double dereferencing - however, I dont understand the
error message - thts what led me on a wild goose chase.

Whats with the "cannot convert parameter 1 from 'ArrayData *const ' to
'const std::string &" ?

I would ave thought that an error msg like this would have been closer
to the mark:

"cannot convert parameter 1 from 'ArrayData *const ' to 'const ArrayData&"

Any suggestions why the compiler was trying to cast the item to a string ?
 
Z

Zeppe

Bart said:
Whats with the "cannot convert parameter 1 from 'ArrayData *const ' to
'const std::string &" ?

I would ave thought that an error msg like this would have been closer
to the mark:

"cannot convert parameter 1 from 'ArrayData *const ' to 'const ArrayData&"

Any suggestions why the compiler was trying to cast the item to a string ?

Well, the only thing I can think at is that when you don't give the
constructor an object that entails the call of the copy constructor, the
compiler assumes that you are going to call a normal constructor. And
since the only constructor that accepts one parameter is that one that
takes a string as first parameter, he's trying to use that, and to
convert the parameter to a string in order to call it.

Regards,

Zeppe
 
B

Ben Schumeth

I have the ff class decl:

class ArrayData : public myArray
{
public:
inline ArrayData(){ InitArray(&m_arr);}
inline explicit ArrayData(const std::string& name):m_name(name){
InitArray(&m_arr);}
inline explicit ArrayData(const ArrayData& arr):m_name(arr.m_name) {
CopyArray(&arr.m_arr, &m_arr) ;}
inline ArrayData& operator= (const ArrayData& rhs)
{
if (this != &rhs){ CopyArray(&rhs.m_arr, &m_arr) ; m_name = rhs.m_name
;}
return *this ;
}
inline ~ArrayData(){ FreeArray(&m_arr); }
inline const std::string& Name() const { return m_name ; }

private:
tpArray m_arr ;
std::string m_name ;
};

Just a little note, unrelated to your question (which people more capable
than I already answered). Any method defined within the class definition
itself is implicitly inline, so there's no need to write it explicitly.

class A
{
int someFunc() { return 0; } // already inline
int otherFunc(); // not inline
int theRealFunc();
};

int
A::eek:therFunc()
{
return 1;
}

inline int
theRealFunc() // explicitly inline
{
return 5;
}
 

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
473,744
Messages
2,569,483
Members
44,902
Latest member
Elena68X5

Latest Threads

Top