簡體   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