Can not call constructors of inherited objects
-
Hello!
I have the following
class A { public: struct { B b; //B and C -- some classes which can be bitwise copied, C c; // thus I do not need in copy constructor of this structure } dataContainer; D d; A(void):dataContainer.b(1.0),dataContainer.c('a'),d(-3){;} //Call constructors of inherited objects -- error here :( }I put some members to the
dataContainerstructure, because I can need, for example, to make a temporary copy of members fromdataContainer, or pass these members to some function etc.But compiler do not like the
dataContainer.b(1.0). I hope that this code will skip thedataContainerdefault constructor (because I do not call it inAconstructor) and instead will directly constructdataContainer.banddataContainer.cwith initial values I need.Another question: what to do with anonymous struct:
{ public: struct { B b; //B and C -- some classes which can be bitwise copied, C c; // thus I do not need in copy constructor of this structure }; //Anonymous struct, all OK here D d; A(void):b(1.0),c('a'),d(-3){;} //Is this OK? }How to make constructor of anonymous struct?
-
SAn schrieb:
Hello!
I have the following
class A { public: struct { B b; //B and C -- some classes which can be bitwise copied, C c; // thus I do not need in copy constructor of this structure } dataContainer; D d; A(void):dataContainer.b(1.0),dataContainer.c('a'),d(-3){;} //Call constructors of inherited objects -- error here :( }I put some members to the
dataContainerstructure, because I can need, for example, to make a temporary copy of members fromdataContainer, or pass these members to some function etc.Being an unnamed structure, it cannot be used to declare a function parameter or return type - this also means that you cannot create a function to serve as a pseudo-constructor (except perhaps a template function through type deduction, but we'll ignore that here). Giving the struct a name should solve the problem, you could then declare a proper constructor for it or use a function instead (that it may stay a POD if necessary).
class A { public: struct dataContainerType { dataContainerType(const B& b,const C& c) : b(b), c(c) {} // use constructor or static dataContainerType make(const B& b,const C& c) { dataContainerType x = { b,c }; return x; } // ordinary function B b; C c; } dataContainer; D d; A(void):dataContainer(dataContainerType::make(1.0,'a')) }Either soultion is equally efficient, as the copy that would have to be made within the function make may be eliminated at the compiler's discretion (NRVO).
As for terms, b and c are not inherited members - that would imply that you dervied from them.Another question: what to do with anonymous struct:
{ public: struct { B b; //B and C -- some classes which can be bitwise copied, C c; // thus I do not need in copy constructor of this structure }; //Anonymous struct, all OK here D d; A(void):b(1.0),c('a'),d(-3){;} //Is this OK? }How to make constructor of anonymous struct?
There are no anonymous structs (that is, declaring an unnamed struct without declaring an object of that type or a derived type or declaring a typedef name at the same time) in Standard C++. And - as indicated above - an unnamed class cannot have user declared constructors or destructors.
-
Thank you!
I understand.Can I write this way:
A(void):dataContainer({1.0,'a'}),d(-3){}?Another problem is that in my code I have the following:
template<_TTP> _Cell<_CTP>::_Cell(_meshPointer const mesh): Structure.parent(NULL),Structure.children(NULL),Structure.fixed(false),Structure.numberOfLeafs(0), Structure.newCell(false),Structure.Adress(mesh),Structure.unsplitable(false),Structure.unmergeable(false),[...]When I reading this code, I see, that the newly constructed cell has no parent, has no children, structure is not fixed and so on...
When I fix it, it becomes completely unreadable:
template<_TTP> _Cell<_CTP>::_Cell(_meshPointer const mesh): Structure(NULL,NULL,false,0,false,mesh,false,false,[...]), [...]
-
If you want it readable in this way, you have to put the assignments in the constructor block, not in its initialization list:
template<_TTP> _Cell<_CTP>::_Cell(_meshPointer const mesh) { Structure.parent = NULL; Structure.children = NULL; Structure.fixed = false; //... }Another way are the so called "named constructors":
http://www.parashift.com/c++-faq-lite/ctors.html#faq-10.8
-
The approach of Th69 is ok if Structure's members are of types without nontrivial ctors. Having types with nontrivial ctors in Structure that approach would give a default-construction of that member during initialization and a copy-assignment in Cell's ctor body.
For structures or classes that have such a long ctor argument list as Structure in your example, one could gain some readability by defining extra types or functions for each (or most) of the ctor arguments.
The definition of an extra type could look like this:struct StrucParent { S* par_; //I don't know what type the parent is, replace that S appropiately StrucParent(S* par) : par_(par) {}; };and then replace the first argument of Structure's ctor with a StrucParent:
class Structure { /* ... */ // Structure(S* parent , *.... //replaced Structure (StrucParent parent, /*...*/); };And then call the Ctor like this:
template<_TTP> _Cell<_CTP>::_Cell(_meshPointer const mesh) : Structure( StrucParent(NULL), StrucChildren(NULL), StrucFixed(false), /*...*/ ), [...]If you cannot (or do not want to) modify Structure's ctor, you could provide some simple inline functions like this:
inline S* StrucParent(S* par) {return par;} inline bool StrucFixed(bool f) {return f;} // etc.And calling the ctor like stated above - but this time the old ctor as you had it before. Here the readability is better than in the original example, without any performance overhead (I'm pretty sure that any compiler will toss away the pass-through functions). The only flaw is that you pollute your surrounding namespace with the names of those functions. That could be solved like that:
//Structure.hpp namespace Struc { inline S* Parent(S* par) {return par;} inline bool Fixed(bool f) {return f;} //etc. } //Cell.hpp template<_TTP> _Cell<_CTP>::_Cell(_meshPointer const mesh) : Structure( Struc::Parent(NULL), Struc::Children(NULL), Struc::Fixed(false), /*...*/ ), [...]Enough readability?

PS: an advantage of the define-new-types-version is, that you can provide ctors of Structure where you leave out different arguments with the same type - thyt otherwise would be ambigous:
Structure::Structure(StrucParent, StrucFixed); //1) ok, presumably children will be set to NULL Structure::Structure(StrucChildren, StrucFixed); //2) this time parent = NULL Structure(S* parent, bool fixed); //3) same as 1 without new types. Structure(S* children, bool fixed); //4) intended to be same as 2) but is abiguous with 3)!!
-
Closed thread because it is a spam bot friend
