Create array of objects with different constructor parameters
-
Hello.
Let us suppose, that I have quaternary tree. Each tree node can have either zero or 4 children. The children are LB,RB,LU and RU nodes. A tree node is the class:
class Node { public: enum position{pLB=0,pRB,pLU,pRU,pRoot}; private: Node *parent; //The parent of the node position pos; //Position of the node in the parent Node *children; //Pointer to array of 4 children (if any) or NULL public: Node(void): parent(NULL), pos(pRoot), children(NULL) //Create root node { ; } Node(Node *parent, position pos): parent(parent), pos(pos), children(NULL) //Create node having parent { ; } ~Node(void) { if(children) delete[] children; } void MakeChildren(void) { if(children) return; children = new Node[4](this,???); //How to create 4 children with (this,LB),(this,RB),(this,LU),(this,RU) constructor parameters? } };I do not have 4 pointers to children nodes because:
- node can have either 0 or 4 children
- 4 pointers need more memory then 1 pointer
- 4 memory allocations by 1 node are slower than 1 memory allocation for 4 nodes
How to create 4 nodes simultaneously? I need to pass them parent and their positions in the parent.
I am using placement new now, but it is ugly.
-
- That is a quadtree, not an octree.
- Why do you want to create them simultaneously? Why not iteratively in a loop? This all together seems to me as an unnecessary microoptimization try.
-
Constructur arguments cannot be passed directly in an array new expression. A default constructor may take default arguments, but since those are looked up in the scope of the class (which is where they are declared) it would involve objects with static storage duration to be used in your case which may not be desirable, esp. in multi-threaded environments.
It may make more sense to aggregate the child nodes in a separate class which upon construction initialises each distinct member in turn.
placement new isn't necessarily bad, if you're adventurous you could also employ the generate algorithm in combination with raw_storage_iterator.
-
Tachyon schrieb:
- That is a quadtree, not an octree.
- Why do you want to create them simultaneously? Why not iteratively in a loop? This all together seems to me as an unnecessary microoptimization try.
- I noticed this. Already corrected.
- I cannot make them in a loop because
childrenin not "array of pointers", it is "pointer to array".
-
camper schrieb:
It may make more sense to aggregate the child nodes in a separate class which upon construction initialises each distinct member in turn.
Excellent!
-
or placement new
-
Hm... Strange error:
enum tChildPos { cpxyz=0,cpXyz,cpxYz,xpXYz,cpxyZ,cpXyZ,cpxYZ,xpXYZ,cpRoot }; class CChildren { private: CCell cells[8]; public: CChildren(Cell *parent); inline CCell &operator[](tChildPos p){return cells[p];} }; CChildren::CChildren(Cell *parent): cells[cpxyz](parent,cpxyz),cells[cpXyz](parent,cpXyz), //It does not like [] :((( cells[cpxYz](parent,cpxYz),cells[cpXYz](parent,cpXYz), cells[cpxyZ](parent,cpxyZ),cells[cpXyZ](parent,cpXyZ), cells[cpxYZ](parent,cpxYZ),cells[cpXYZ](parent,cpXYZ) { ; }
-
There is no syntactic form to initialise an array member in a constructor with specific arguments. That situation is essentially the same as it is for new expressions, the only possible initialiser for arrays is an empty one which results in value-initialization (and so default construction of its elements here). C++0x will bring significant improvements to this. Within the current standard you will need to use individually named members
class CChildren { private: CCell cell0,cell1,cell2,cell3,cell4,cell5,cell6,cell7; ... CChildren::CChildren(Cell *parent) : cell0(parent,cpxyz),cell1(parent,cpxyz), cell2(parent,cpxyz),cell3(parent,cpxyz), cell4(parent,cpxyz),cell5(parent,cpxyz), cell6(parent,cpxyz),cell7(parent,cpxyz) {}It can be awkward to define subscripting in this case. A union may help but unfortunately, while consecutive member of a class must be allocated at increasing addresses if no intervening access specifier is present, there may be internal padding other than that which is strictly neccessary to achieve proper alignment (padding is never needed for that purpose between members of the same type). However, because of its usefulness and wide support by compilers it can still make sense to rely on no padding between members and write thus
class CChildren { ... CCell& operator[](tChildPos p) { typedef CCell array_type[8]; // fail, if compiler unexpectedly adds padding: // BOOST_STATIC_ASSERT(( sizeof( array_type ) == sizeof( CChildren ) )); return reinterpret_cast<array_type&>(cell0)[p]; } ...on a side note: don't use capital C to signify classes. That letter (similar to capital T in the Borland world) was originally introduced to prevent name clashes with user declared ids, therefore using it for your classes subverts its purpose. Questionable as the Hungarian notation may be, that capital C has nothing to do with it. When not in Rome don't do as Romans do (i.e. when you're not working on code of the frameworks in question).
-
One year ago you said me that I should not use underscores (
_Cell) to identify classes. Now you say that I should not use letter "C" (CCell) for that purpose.
What is a correct method to distinguish between types names and variables names?
In word processors I can use bold or red text for that purpose. But in C++ I can not use custom formatting
It will be good that red and green identifiers with same name are considered as different identifiers.
By the way, Visual Studio alows me to use any unicode symbols for identifiers:
double const π(3.141592653589793238462643383279502884197169399375105820974944592307816406286208998628034825342117);Is that portable?
-
SAn schrieb:
One year ago you said me that I should not use underscores (
_Cell) to identify classes. Now you say that I should not use letter "C" (CCell) for that purpose.
What is a correct method to distinguish between types names and variables names?
In word processors I can use bold or red text for that purpose. But in C++ I can not use custom formatting
It will be good that red and green identifiers with same name are considered as different identifiers.
I do not use prefixes, I prefer diffrent styles of writing:
class Class; int my_var(0); const int MY_CONST(0);SAn schrieb:
By the way, Visual Studio alows me to use any unicode symbols for identifiers:
double const π(3.141592653589793238462643383279502884197169399375105820974944592307816406286208998628034825342117);Is that portable?
Nope.
-
Octree is working. Thank you!
Here is a result: http://keep4u.ru/imgs/b/080605/6d/6d685b154a62067518.jpg
-
SAn schrieb:
Octree is working. Thank you!
Here is a result: http://keep4u.ru/imgs/b/080605/6d/6d685b154a62067518.jpgHey. That looks nice. But normally the detailed part should be near to the camera or is this intented?
-
Detalization depend on the values stored in mesh, not on the camera position.