Проблема перегрузки конструктора в C ++ Наследование - PullRequest
0 голосов
/ 11 июня 2010

Вот мой фрагмент кода:

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 constructor.

Есть ли какой-нибудь способ избавиться от этой ситуации?

Я могу создать другую функцию, которая выполняет ту работу, которую я хочу сделать, и оба конструктора вызывают эту функцию.Но интересно, есть ли решение?

Редактировать: http://www.parashift.com/c++-faq-lite/ctors.html#faq-10.3

Ответы [ 3 ]

6 голосов
/ 11 июня 2010

Код не делает то, что вы, вероятно, думаете, что он делает. Линия:

 LoginRequest::LoginRequest();     

создает временный объект, который немедленно уничтожается. как предлагали другие, вы можете поместить дублированный код в приватную функцию, но это имеет много проблем - в частности, такая функция может выполнять только присваивание, а не инициализацию, и многие классы не поддерживают присваивание. Несколько лучшим решением является реализация одного конструктора с аргументом по умолчанию:

class LoginRequest {
   ....
   LoginRequest( QDomDocument d = DefaultDoc() );
};
2 голосов
/ 11 июня 2010

Да, ваше решение использовать функцию и вызывать ее из обоих конструкторов - хорошее (или, может быть, лучше: создать иерархию классов Request - LoginRequest - LoginRequestWithDoc).

C # предоставляет то, что вам нужно / пыталось достичь, но не C ++: ctor класса вызывает другой ctor того же класса.

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

  public LoginRequest( Document doc )
    : this()   // <<< order of execution: Request() -> LoginRequest()
               //                         -> LoginRequest( doc )
  {
    // ...
  }
}
1 голос
/ 11 июня 2010

Я могу создать другую функцию, которая выполняет ту работу, которую я хочу сделать, и оба конструктора вызывают эту функцию. Но мне интересно, есть ли решение?

Да, есть:

Сначала переместите код для инициализации в список инициализации. Это более эффективная и хорошая практика кодирования.

Во-вторых, любой код, который является общим для обоих конструкторов и не инициализируется (то есть его нельзя поместить в список инициализации), следует переместить в общую частную функцию и вызвать из обоих конструкторов.

Обычно нецелесообразно вызывать конструктор из другого конструктора, поскольку - в зависимости от того, что делает компилятор, у вас может быть странное / неопределенное поведение (в этом случае базовый класс инициализируется дважды).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...