Нет соответствующего вызова конструктора по умолчанию, при использовании QVector - PullRequest
0 голосов
/ 14 января 2019

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

a.h

#ifndef A_H
#define A_H

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

#endif // A_H

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

Ответы [ 2 ]

0 голосов
/ 14 января 2019

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

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

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

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

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

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

Не забудьте и конструктор копирования & hellip; и правильная квалификация в этом A::function() определении.

Предварительная декларация не решит эту проблему, и при этом она вам не понадобится. Фактически, добавление одного к этой конкретной программе ничего не изменит. ;)

0 голосов
/ 14 января 2019

Первый в a.cpp определение функции обновления:

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

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

...