传递对构造函数的引用,默认参数

时间:2014-05-05 15:31:37

标签: c++ qt constructor qcustomplot

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

它应该是这样的:

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


}

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

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

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

4 个答案:

答案 0 :(得分: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实例的生命周期内永远不会被销毁,并将其用作引用。

答案 1 :(得分:1)

如果你想使用默认参数(对于函数或模板),没有办法指出跳过的参数,你只能在结尾处留下一些。
因此,C ++会强制您为具有此类参数的任何参数提供默认值 如果第二个没有良好的默认值,但对于第一个,使用多个构造函数或更改参数排序。

如果您确实要为l值引用参数(非常量和非移动)提供默认值,请使用全局静态对象。
对于其他引用/非引用,只需构建一个对象即可。

如果您确实应该得到未定义的行为,请不要试图强制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);
}

答案 2 :(得分:1)

根据C ++标准

  

在给定的函数声明中,a之后的每个参数   带有默认参数的参数应具有默认参数   在本声明或之前的声明中提供或应作为一种功能   参数包。

  

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

答案 3 :(得分:0)

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

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

  

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

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

问题是您尝试使用没有有效对象的引用。您需要初始化对“有效”对象的引用。您可以通过代理对象将其初始化为null指针,这是引用。你可以设置一个临时对象的const引用,但是当临时被破坏时会产生未定义的行为。

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

所以,我个人会这样写:

头文件

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

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

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