Нет соответствующего вызова конструктора по умолчанию при использовании QVector

У меня есть класс B, который создает объект класса A и вызывает метод объекта.

a.h

#ifndef A_H
#define A_H

class A
{
public:
    A(int);
    void function();
};

#endif // A_H

а.cpp

#include "a.h"

A::A(int x)
{

}
void A::function(){
    //Do something.
}

b.h

#ifndef B_H
#define B_H
#include <QVector>
#include <a.h>


class B
{
public:
    B(int);
    QVector<A> list;
};

#endif // B_H

b.cpp

#include "b.h"

B::B(int y)
{
    list.append(A(y));
    list[0].function();
}  

Проблема в том, что это не компилируется. Он возвращает «нет подходящей функции для вызова« A: A() »». Я знаю, что это можно решить с помощью предварительного объявления, но здесь это не работает, так как я хочу вызвать функцию «функция». Я также не хочу включать весь класс A в класс B.


person Luca9984    schedule 14.01.2019    source источник
comment
Похоже, Qt запрашивает конструктор по умолчанию.   -  person TrebledJ    schedule 14.01.2019
comment
ваша интерпретация не совсем верна. отсутствие соответствующей функции для вызова 'A:A()' означает, что A не имеет конструктора по умолчанию, но вы пытаетесь его вызвать   -  person 463035818_is_not_a_number    schedule 14.01.2019


Ответы (2)


Как и во многих контейнерах Qt, тип элемента QVector должен быть назначаемым типом данных. в вашей версии.

В отличие от стандартной библиотеки, Qt определяет это как:

Значения, хранящиеся в различных контейнерах, могут относиться к любому назначаемому типу данных. Чтобы соответствовать требованиям, тип должен предоставлять конструктор по умолчанию, конструктор копирования и оператор присваивания.

Это действительно прискорбно, потому что в вашем примере нет практической необходимости в конструкторе по умолчанию, и действительно std::vector будет (соответственно) позволяют использовать тип элемента, у которого его нет.

Функция QVector::value(int) использует это свойство, но вы его не используете! Разработчики Qt должны выполнять какие-то проверки заранее, а не использовать подход стандартной библиотеки «просто проверяйте предварительные условия, когда они действительно необходимы», иначе это «случайность» кода!

Как следствие, до версии 5.13, в которой это было изменено, вам придется указать A конструктор по умолчанию, извините.

Не забывайте также о конструкторе копирования и правильной квалификации для этого определения A::function().

Предварительное объявление не решит эту проблему, оно вам и не нужно. На самом деле, добавление одного в эту конкретную программу буквально ничего не даст. ;)

person Lightness Races in Orbit    schedule 14.01.2019
comment
Альтернативное решение — переключиться на std::vector, конечно. - person Martin Bonner supports Monica; 14.01.2019
comment
Всем хороших новостей! Требование конструктора по умолчанию для QVector было окончательно исключено в версии 5.13 (зафиксировать). - person peppe; 14.01.2019
comment
Разработчики Qt должны выполнять какие-то проверки заранее, а не использовать подход стандартной библиотеки, просто проверяя предварительные условия, когда они действительно необходимы. Это еще хуже... это просто неаккуратное кодирование, например. вызов resize() из функций вставки или что-то в этом роде :-( - person peppe; 14.01.2019
comment
@peppe: Возможно. Возможно, нет. (Игнорируйте, если вы буквально знаете об обратном из источника!) - person Lightness Races in Orbit; 14.01.2019
comment
Кровавые подробности: в версии 5.12 detach() (вызываемая любой неконстантной функцией, например функциями вставки) вызывает reallocData(), универсальную функцию, которая выполняет отсоединение, выделение, изменение размера, резервирование и так далее. Результатом является навязанное требование. Другие функции также небрежно закодированы (например, clear() в 5.12 вызывает resize(0)). - person peppe; 14.01.2019

Сначала в a.cpp определении функции обновления:

void A::function(){  // A: added
    //Do something.
}

Во-вторых, я бы добавил конструктор копирования A(const A&), так как он может понадобиться списку для целей перераспределения внутреннего буфера.

person grapes    schedule 14.01.2019
comment
Хотя вы правы в том, что определение function в настоящее время не работает и что следует добавить конструктор копирования, ничто из этого не отвечает на вопрос о том, почему вызывается конструктор по умолчанию и как лучше всего это решить. - person Lightness Races in Orbit; 14.01.2019