Reputation: 13929
Here my code snippet:
class Request
{
public:
Request(void);
………..
}
Request::Request(void)
{
qDebug()<<"Request: "<<"Hello World";
}
class LoginRequest :public Request
{
public:
LoginRequest(void);
LoginRequest(QDomDocument);
……………
}
LoginRequest::LoginRequest(void)
{
qDebug()<<"LoginRequest: "<<"Hello World";
requestType=LOGIN;
requestId=-1;
}
LoginRequest::LoginRequest(QDomDocument doc){
qDebug()<<"LoginRequest: "<<"Hello World with QDomDocument";
LoginRequest::LoginRequest();
xmlDoc_=doc;
}
When call constructor of Overrided LoginRequest
LoginRequest *test=new LoginRequest(doc);
I came up with this result:
Request: Hello World
LoginRequest: Hello World with QDomDocument
Request: Hello World
LoginRequest: Hello World
Obviously both constructor of LoginRequest called REquest constructor.
Is there any way to cape with this situation?
I can construct another function that does the job I want to do and have both constructors call that function. But I wonder is there any solution?
Edit: http://www.parashift.com/c++-faq-lite/ctors.html#faq-10.3
Upvotes: 0
Views: 1897
Reputation:
The code is not doing what you probably think it is doing. The line:
LoginRequest::LoginRequest();
constructs a temporary object which is immediately destroyed. as others have suggested, you can put duplicate code in a private function, but this has a lot of issues - specifically, such a function can only perform assignment, not initialisation, and many classes do not support assignment. A somewhat better solution is to implement a single constructor with a default argument:
class LoginRequest {
....
LoginRequest( QDomDocument d = DefaultDoc() );
};
Upvotes: 6
Reputation: 27365
I can construct another function that does the job I want to do and have both constructors call that function. But I wonder is there any solution?
Yes, there is:
First, move the code for initialization into an initialization list. It is more efficient and good coding practice.
Second, Any code that's common to both constructors and not an initialization (that is, it cannot be put in an initialization list) should be moved to a common private function and called from both constructors.
Usually it is not good to call a constructor from another constructor as - depending on what the compiler is doing you may have strange/undefined behavior (in this case the base class gets initialized twice).
Upvotes: 1
Reputation: 2947
Yes, your solution to use a function and call it from both constructors is a good one (oder maybe better: make a class hierarchy Request - LoginRequest - LoginRequestWithDoc).
C# provides what you need/tried to achieve but not C++: a ctor of a class call another ctor of the same class.
class LoginRequest
{
public LoginRequest()
{
// ...
}
public LoginRequest( Document doc )
: this() // <<< order of execution: Request() -> LoginRequest()
// -> LoginRequest( doc )
{
// ...
}
}
Upvotes: 2