Передача ссылки на конструктор, аргумент по умолчанию

Я создаю собственный класс Qt C +, который должен принимать ссылку на QCustomPlot из ui-> в качестве входного аргумента для конструктора.

Это должно выглядеть так:

myPlots::myPlots(QObject *parent, QCustomPlot& _plot ) :
QObject(parent), plot(_plot)
{}

Я не хочу создавать область графика программно, как это нужно делать в редактировании пользовательского интерфейса. И я не хочу использовать указатель в качестве аргумента, так как ссылки безопаснее и понятнее синтаксиса, как я понимаю. Однако я получаю следующую ошибку:

«ошибка: отсутствует аргумент по умолчанию для параметра 2 в myPlots :: myPlots (QObject *, QCustomPlot&)»
явный myPlots (QObject * parent = 0, QCustomPlot& _сюжет);»

Я попытался = 0 и = null в качестве аргумента по умолчанию, но получил только ошибки. Что здесь происходит?

0

Решение

Ошибка в вашем вопросе заключается в том, что аргументы со значениями по умолчанию должны быть после аргументы без значений по умолчанию, это правила C ++.


Что касается наличия _plot аргумент, имеющий значение по умолчанию, это отчасти зависит от того, как plot переменная-член объявлена. Если это не ссылка, вы можете сделать _plot аргумент ссылка на константу вместо этого и имеет конструкцию по умолчанию QCustomPlot объект в качестве значения по умолчанию:

myPlots(QObject *parent = nullptr, const QCustomPlot& _plot = QCustomPlot(parent));

Однако это работает, только если plot участник не ссылка. Если оно является ссылка, то вы, вероятно, должны иметь два конструктора: один принимает QCustomPlot ссылка, а одна без:

myPlots(QObject *parent = nullptr);
myPlots(QCustomPlot& plot_, QObject *parent = nullptr);

Первый конструктор должен создать QCustomPlot экземпляр, который никогда не разрушается в течение жизни myPlots экземпляр создается, и используйте его для справки.

4

Другие решения

Согласно стандарту C ++

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

а также

Ссылка должна быть инициализирована для ссылки на действительный объект или
функция. [Примечание: в частности, нулевая ссылка не может существовать в
четко определенная программа, потому что единственный способ создать такую ​​ссылку
было бы связать его с «объектом», полученным косвенным путем через
нулевой указатель, который вызывает неопределенное поведение.

1

Если вы хотите использовать аргументы по умолчанию (для функций или шаблонов), нет способа указать пропущенный аргумент, вы можете оставить только некоторые в конце.
Поэтому C ++ заставляет вас указывать значения по умолчанию для любого аргумента, следующего за аргументом, имеющим такой аргумент.
Если для второго нет хорошего значения по умолчанию, а для первого, используйте несколько конструкторов или измените порядок аргументов.

Если вы действительно хотите задать значение по умолчанию для ссылочного аргумента с l-значением (не-const и non-move), используйте глобальный статический объект.
Для других ссылок / не-ссылок, создание объекта просто там хорошо.

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

Пример для статического объекта:

struct myPlots {
explicit myPlots(QObject *parent = 0, QCustomPlot& _plot = standard_plot);
static QCustomPlot standard_plot;
}

Пример для переупорядочения:

struct myPlots {
explicit myPlots(QCustomPlot& _plot, QObject *parent = 0);
}

Пример для перегрузок:

struct myPlots {
myPlots(QObject *parent, QCustomPlot& _plot);
explicit myPlots(QCustomPlot& _plot);
}
1

Не рекомендуется устанавливать ссылку на ноль или NULL прямо или косвенно. Честно говоря, его установка напрямую, вероятно, не сработает, потому что не удастся скомпилировать, а остальные будут иметь неопределенное поведение.

Тем не менее, компилятор пытается помочь вам, как использовать конструктор:

myPlots :: myPlots (QObject * parent, QCustomPlot& _сюжет ) :
QObject (parent), plot (_plot)

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

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

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

Итак, я бы лично написал что-то вроде этого:

заголовочный файл

explicit myPlots(QCustomPlot _plot, QObject *parent = Q_NULLPTR);

или же

explicit myPlots(QCustomPlot *_plot = 0, QObject *parent = Q_NULLPTR);

Прежде чем начать спрашивать о Q_NULLPTR в комментарии это не волшебно. Это скрытый драгоценный камень, но его можно использовать свободно, так как, по словам сопровождающего, он не сломается. Это просто возвращается к 0 без поддержки C ++ 11 или более поздней версии, в противном случае nullptrТаким образом, ваше программное обеспечение будет работать с обоими.

0
По вопросам рекламы [email protected]