这是我的代码段:
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;
}
当Overrided LoginRequest的调用构造函数
时LoginRequest *test=new LoginRequest(doc);
我想出了这个结果:
Request: Hello World
LoginRequest: Hello World with QDomDocument
Request: Hello World
LoginRequest: Hello World
显然,LoginRequest的构造函数都调用了REquest构造函数。
有没有办法解决这种情况?
我可以构造另一个函数来完成我想要做的工作,并让两个构造函数都调用该函数。但我想知道有什么解决方案吗?
编辑: http://www.parashift.com/c++-faq-lite/ctors.html#faq-10.3
答案 0 :(得分:6)
代码没有做你认为它正在做的事情。这一行:
LoginRequest::LoginRequest();
构造一个立即销毁的临时对象。正如其他人所建议的那样,你可以将重复的代码放在私有函数中,但这有很多问题 - 具体来说,这样的函数只能执行赋值,而不能初始化,而且很多类都不支持赋值。一个更好的解决方案是使用默认参数实现单个构造函数:
class LoginRequest {
....
LoginRequest( QDomDocument d = DefaultDoc() );
};
答案 1 :(得分:2)
是的,您使用函数并从两个构造函数中调用它的解决方案是一个很好的解决方案(或许更好:创建类层次结构Request - LoginRequest - LoginRequestWithDoc)。
C#提供了你需要/试图实现的东西而不是C ++:一个类的ctor调用同一个类的另一个ctor。
class LoginRequest
{
public LoginRequest()
{
// ...
}
public LoginRequest( Document doc )
: this() // <<< order of execution: Request() -> LoginRequest()
// -> LoginRequest( doc )
{
// ...
}
}
答案 2 :(得分:1)
我可以构造另一个函数来完成我想要做的工作,并让两个构造函数都调用该函数。但我想知道有什么解决方案吗?
是的,有:
首先,将初始化代码移动到初始化列表中。它是更有效和更好的编码实践。
第二,任何对两个构造函数都通用而不是初始化的代码(也就是说,它不能放在初始化列表中)应该被移动到一个公共私有函数并从两个构造函数调用。
通常从另一个构造函数调用构造函数是不好的 - 根据编译器的作用,您可能会有奇怪/未定义的行为(在这种情况下,基类会被初始化两次)。