繁体   English   中英

将引用传递给构造函数,默认参数

[英]Passing reference to constructor, default argument

我正在创建一个自己的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用作默认参数,但只有错误。 这是怎么回事

您问题中的错误是因为具有默认值的参数必须没有默认值的参数之后 ,这些是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实例的生存期内不会被破坏,并将其用作参考。

如果要使用默认参数(用于函数或模板),则无法指示跳过的参数,只能在最后保留一些参数。
因此,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);
}

根据C ++标准

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

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

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

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

myPlots :: myPlots(QObject * parent,QCustomPlot&_plot):QObject(parent),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 ,因此您的软件将可以同时使用。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM