【问题标题】:Constructor Overload Problem in C++ InheritanceC++ 继承中的构造函数重载问题
【发布时间】:2010-06-11 11:38:34
【问题描述】:

这是我的代码 sn-p:

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

【问题讨论】:

  • 您为什么要处理这种情况?您正在创建两个LoginRequests。显然这意味着你有 2 个请求,并且请求 ctor 应该被调用两次。
  • 其实我是想创建一个LoginRequest,但现在我明白了。

标签: c++ inheritance constructor overloading


【解决方案1】:

代码并没有像您认为的那样做。行:

 LoginRequest::LoginRequest();     

构造一个立即销毁的临时对象。正如其他人所建议的那样,您可以将重复的代码放在私有函数中,但这有很多问题 - 具体来说,这样的函数只能执行赋值,不能初始化,而且许多类不支持赋值。更好的解决方案是使用默认参数实现单个构造函数:

class LoginRequest {
   ....
   LoginRequest( QDomDocument d = DefaultDoc() );
};

【讨论】:

  • @metdos 因为它(大概)在初始化发生后被调用。我不明白你的第二条评论。
  • @metdos 抱歉 - 还是不明白。它是一个变量,你可以像使用其他变量一样使用它。
  • @Neil Butterworth 对不起,现在我明白你的意思了。谢谢。
【解决方案2】:

是的,您使用一个函数并从两个构造函数调用它的解决方案是一个很好的解决方案(或者更好:创建一个类层次结构 Request - LoginRequest - LoginRequestWithDoc)。

C# 提供了您需要/尝试实现但 C++ 不具备的功能:一个类的 ctor 调用同一类的另一个 ctor。

class LoginRequest
{
  public LoginRequest()
  {
    // ...
  }

  public LoginRequest( Document doc )
    : this()   // <<< order of execution: Request() -> LoginRequest()
               //                         -> LoginRequest( doc )
  {
    // ...
  }
}

【讨论】:

  • 虽然它会在 C++0x 中。
【解决方案3】:

我可以构造另一个函数来完成我想做的工作,并让两个构造函数都调用该函数。但我想知道有什么解决办法吗?

是的,有:

首先,将初始化代码移动到初始化列表中。它是更高效和良好的编码实践。

其次,任何对两个构造函数都通用的代码而不是初始化(即,它不能放在初始化列表中)应该移动到一个公共私有函数并从两个构造函数调用。

通常从另一个构造函数调用构造函数是不好的 - 取决于编译器正在做什么,您可能会有奇怪/未定义的行为(在这种情况下,基类被初始化两次)。

【讨论】:

  • 不,基类没有初始化两次。创建了一个完全不同的基类实例。
猜你喜欢
  • 2021-06-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-03-24
  • 2014-08-21
  • 2012-12-22
相关资源
最近更新 更多