问题
I'm currently having an assignment, in which i need to create a DATABASE class,
which contains a employees pointers array, and private inner class,
that defines employees linked list
the goal to accomplish here, according to the assignment, is working acording
to a DB_TYPE defined constant.
when DB_TYPE = 0 i need my class methods to work with the employees pointers array,
when DB_TYPE = 1 i need my class methods to work with the employees linked list.
Therefore, i need two things:
1. Understanding constructor calling -
When i construct a new DATABASE object, for example with no paramaters,
the default constructor is called.
How do i call the linked list inner constructor to construct a Node, from the constructor itself?
2. Working according to the DB_TYPE constant -
I Suppose that's less of a trouble, as i can set my methods to work with
two cases\or with 'if' conditions regarding each value of DB_TYPE.
but if that's not that simple, i'll be glad to get some advise\help on how to do so.
EDIT: My Current code:
class DataBase {
public:
DataBase();
private:
Employee ** empArr; /*!< Employees pointers array */
unsigned int empCount;
Node head;
class Node{
public:
Node();
Node(Employee * emp, Node * next);
private:
Employee * emp; /*!< Employee Pointer */
Node * next; /*!< The next node (containing the next employee) */
};
};
Thanks,
Adiel
回答1:
The Node node;
has to come after the definition of class Node
.
To invoke a non-default constructor of node
when creating a Database
you use the constructor initialization list:
Database::Database()
: head(foo, bar)
, empCount(0)
, empArr(nullptr)
{
}
You can and should initialize the other members in this list too. If the object needs complicated initialization you can write a function to do that; initializing via the constructor body should be a last resort. (well, a later resort, it's not a terrible thing).
Note that the order member objects are initialized is the order they appear in the class definition - not the order they appear in the constructor init list. So if, for example, your head
's constructor argument had to be worked out from empArr
, you would have to make sure that Node head;
came after Employee **empArr;
, and also you'd have to write a function to set up empArr
so your list would look like
: empCount(5), empArr( allocate_emparr(5) ), head(empArr[0], nullptr)
Re. DB_TYPE
. Since it is preprocessor you can do, wherever appropriate,
#if DB_TYPE
// code for processing linked list
#else
// code for processing pointers array
#endif
This is very powerful, although some people consider it ugly. It's be nicer to use a template instead, especially if the class definition can stay the same and it is only a small number of functions whose behaviour needs to change. However it is challenging to write the template version well if you have not used templates much before.
Example declarations (could be class members or free functions):
template<int N> void do_something(void);
template<> void do_something<0>(void) { /* process pointers array */ }
template<> void do_something<1>(void) { /* process linked list */ }
Usage:
void other_func(void)
{
do_something<DB_TYPE>();
}
来源:https://stackoverflow.com/questions/23844715/nested-class-and-constructor-calling-understanding