0

我正在创建一个自己的 Qt C+ 类,它应该从 ui-> 引用 QCustomPlot 作为构造函数的输入参数。

它应该如下所示:

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


}

我不想以编程方式创建绘图区域,因为它在 UI 编辑中更简洁。并且不希望使用指针作为参数,因为据我了解,引用更安全且语法更简洁。但是我收到以下错误:

“错误:'myPlots::myPlots(QObject*, QCustomPlot&)' 显式 myPlots(QObject *parent=0, QCustomPlot& _plot) 的参数 2 缺少默认参数;”

我尝试将 =0 和 =null 作为默认参数,但只得到错误。这里发生了什么?

4

4 回答 4

4

您问题中的错误是因为具有默认值的参数必须没有默认值的参数之后,这是 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实例,并将其用作引用。

于 2014-05-05T15:33:45.050 回答
1

如果您想使用默认参数(用于函数或模板),则无法指示跳过的参数,您只能在最后留下一些。
因此,C++ 强制您为具有此类参数的任何参数提供默认值。
如果第二个没有好的默认值,但第一个,使用多个构造函数或更改参数顺序。

如果您真的想为左值引用参数(非常量和非移动)提供默认值,请使用全局静态对象。
对于其他引用/非引用,构造一个对象就可以了。

不要试图用可爱的技巧强迫 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);
}
于 2014-05-05T15:41:27.633 回答
1

根据 C++ 标准

在给定的函数声明中,带有默认实参的形参后面的每个形参都应具有在此声明或先前声明中提供的默认实参,或者应为函数形参包。

应初始化引用以引用有效的对象或函数。[注意:特别是,在定义良好的程序中不能存在空引用,因为创建此类引用的唯一方法是将其绑定到通过空指针间接获得的“对象”,这会导致未定义的行为。

于 2014-05-05T15:42:03.533 回答
0

直接或间接地设置对零或 NULL 的引用不是一个好主意。公平地说,直接设置它可能甚至不起作用,因为它将无法编译,其余的将具有未定义的行为。

但是,编译器正在尝试帮助您如何使用构造函数:

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

在设置父级的构造函数中,您通常将父级作为具有默认空指针值的最后一个参数,或者您仅获得父级的重载版本。虽然这不是这里的主要问题。

问题是您试图使用没有有效对象的引用。您需要初始化对“有效”对象的引用。您可以通过代理对象将其初始化为空指针,这就是引号。您可以设置对临时对象的 const 引用,但这将具有未定义的行为,因为临时对象会突然被破坏。

我个人建议重新考虑您的设计并使用指针或值语义。一般来说,参考文献很好,但在这种特殊情况下,我看不到它的好处。

所以,我个人会写这样的东西:

头文件

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

或者

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

在您开始在评论中询问之前Q_NULLPTR,这并不神奇。它是一个隐藏的宝石,但可以自由使用它,因为维护者说它不会损坏。它只是回退到0没有 C++11 或更高版本的支持,否则它被定义为nullptr,因此您的软件将同时使用两者。

于 2014-05-05T15:43:43.067 回答