【问题标题】:How to use an initializer list on a derived class?如何在派生类上使用初始化列表?
【发布时间】:2019-12-29 15:13:42
【问题描述】:

我正在编写一个Qt 应用程序,其中我有一个派生类QDialog。我的派生类还为几个私有成员(通过构造函数设置)使用初始化列表。现在,即使在允许的语法方面,我也有些困惑。我找到了这个post,尝试在我的小演示脚本中跟踪它并提出以下内容:

#include <QString>
#include <QSettings>
#include <QtWidgets/QWidget>
#include <QtWidgets/QDialog>

class foo : QDialog 
{
    Q_OBJECT
    public:
        foo(QSettings* const set=nullptr, const QString s="", QWidget *parent=nullptr) :  QDialog{
        public:
            foo(QSettings* const set=nullptr, const QString s="", QWidget *parent): QDialog(parent){}
        };
        QString nme_get() {return name;}
        void qux(void);
        
    private:
         const QString name;
         QSettings * const settings; 
};

void foo::qux(void) {
    QSettings *test = settings;
    QString name = nme_get();
    test->beginGroup(name);
    /*
     * ...
    */
    test->endGroup();
}


int main (void) {
    QWidget *parent = nullptr;
    QSettings *sttngs = new QSettings(QSettings::NativeFormat,QSettings::UserScope,"GNU","scaper",nullptr
);
    foo inst{sttngs, QString("quux"), parent};
    inst.qux();
        
    return 0;    
}

编译器抛出的:

foo.cpp: In constructor ‘foo::foo(QSettings*, QString, QWidget*)’:
foo.cpp:12:9: error: expected primary-expression before ‘public’
         public:
         ^
foo.cpp:12:9: error: expected ‘}’ before ‘public’
foo.cpp:12:9: error: no matching function for call to ‘QDialog::QDialog(<brace-enclosed initializer list>)’
In file included from /usr/include/x86_64-linux-gnu/qt5/QtWidgets/QDialog:1:0,
                 from foo.cpp:4:
/usr/include/x86_64-linux-gnu/qt5/QtWidgets/qdialog.h:93:5: note: candidate: QDialog::QDialog(QDialogPrivate&, QWidget*, Qt::WindowFlags)
     QDialog(QDialogPrivate &, QWidget *parent, Qt::WindowFlags f = 0);
     ^
/usr/include/x86_64-linux-gnu/qt5/QtWidgets/qdialog.h:93:5: note:   candidate expects 3 arguments, 1 provided
/usr/include/x86_64-linux-gnu/qt5/QtWidgets/qdialog.h:54:14: note: candidate: QDialog::QDialog(QWidget*, Qt::WindowFlags)
     explicit QDialog(QWidget *parent = 0, Qt::WindowFlags f = 0);
              ^
/usr/include/x86_64-linux-gnu/qt5/QtWidgets/qdialog.h:54:14: note:   conversion of argument 1 would be ill-formed:
foo.cpp:11:9: error: uninitialized const member in ‘class QSettings* const’ [-fpermissive]
         foo(QSettings* const set=nullptr, const QString s="", QWidget *parent=nullptr) :  QDialog{
         ^
foo.cpp:21:28: note: ‘QSettings* const foo::settings’ should be initialized
          QSettings * const settings; 
                            ^
foo.cpp:12:9: error: expected ‘{’ before ‘public’
         public:

我知道出现错误是因为我没有正确地将类型提交给基类,但我不确定如何修改它以使其工作... 也在https://doc.qt.io/qt-5/qdialog.html 它说:QDialog(QWidget *parent = nullptr, Qt::WindowFlags f = Qt::WindowFlags()),编译器说:qdialog.h:93:5: note: candidate: QDialog::QDialog(QDialogPrivate&amp;, QWidget*, Qt::WindowFlags)——这让我很困惑,我是不是使用了错误的头文件?

【问题讨论】:

  • 从你的构造函数中移除: QDialog{。事实上,整行可以被删除,因为你在它下面定义了构造函数。

标签: c++ linux qt g++ initializer-list


【解决方案1】:

在定义 c++ 类时,一般的想法是在头文件(.h 文件)中声明和记录类方法,并在 cpp 文件中实现。我目前正在编写没有编辑器的代码,所以可能会有一些语法错误,但它会让你朝着正确的方向前进:

在h文件中:

#include <QString>
#include <QSettings>
#include <QtWidgets/QWidget>
#include <QtWidgets/QDialog>

class foo : public QDialog 
{
    Q_OBJECT
    public:
        foo(QSettings* const set=nullptr, const QString s="", QWidget *parent=nullptr);
        QString nme_get();
        void qux(); //Removed the void parameter here

    private:
         const QString name;
         QSettings * const settings; 
};

在cpp文件中:

// Or whatever your h file is named
#include "foo.h" 

foo::foo(QSettings* const set=nullptr, const QString s="", QWidget *parent=nullptr)
    :QDialog(parent) {
    // Do constructor stuff here (like initializing name for instance)
}

void foo::nme_get() {
    return name;
}

void foo::qux() {
    QSettings *test = settings;
    QString name = nme_get();
    test->beginGroup(name);
    /*
     * ...
    */
    test->endGroup();
}

【讨论】:

  • 来自 OP 的评论:“如您所见,我确实尝试在构造函数中初始化 QSettings * const 设置,但编译器不会接受它,我也在标题中尝试过。我该怎么做妥善解决这个问题?”
  • @stdcerr 因此,您在上面发布的代码存在一些语法错误,这就是我建议重写的原因。您定义构造函数的方式根本不是有效的 C++ 代码(使用 : QDialog { ... }
【解决方案2】:

你的类 foo 没有从 QDialog 继承。将您的第六行更改为:

class foo : public QDialog {

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-10
    • 2022-12-03
    • 2020-08-19
    • 1970-01-01
    • 1970-01-01
    • 2022-01-21
    相关资源
    最近更新 更多