如何初始化c ++类成员

时间:2013-12-27 09:39:12

标签: c++ qt reference

我是c ++的新手,我使用Qt在VS2010中拥有以下代码:

// test.h
#pragma once

#include <QtWidgets/QMainWindow>
#include "ui_test.h"
#include "testDevice.h"
#include "testControl.h"

class test : public QMainWindow
{
    Q_OBJECT

public:
    test(QWidget *parent = 0) : control(device,0) {}
    ~test();

private:
    Ui::testClass ui;
    testDevice device;
    testControl control;
};


// test.cpp
#include "test.h"

test::test(QWidget *parent) : QMainWindow(parent)
{
    ui.setupUi(this);    
    device.start();  
    control.start();

}    

test::~test()
{

}

// testControl.h
#pragma once

#include <QThread>
#include "testDevice.h"

class testControl : public QThread 
{
    Q_OBJECT

public:
    testControl(testDevice& device, QObject *parent = 0);

protected:
    void run(void);

private:
    testDevice device;

    ~testControl(void);
};

// testControl.cpp

#include "testControl.h"


testControl::testControl(testDevice& thisDevice, QObject *parent) : QThread(parent) 
{
}

void testControl::run(void)
{
}


testControl::~testControl(void)
{
}

VS2010说“没有合适的默认构造函数”,它标记:

test::test(QWidget *parent) : QMainWindow(parent)
{

test::~test()

作为错误来源。我曾尝试使用testControl作为指针并作为参考,但我还有很多其他错误......有人可以帮我解决这个问题并向我解释发生了什么事吗?

3 个答案:

答案 0 :(得分:5)

您在标题的test类定义中提供了test构造函数的隐式内联定义:

test(QWidget *parent = 0) : control(device,0) {}

这很可能是编译器所抱怨的。除此之外,您还可以在.cpp文件中提供不同的定义。您只能拥有一个定义。

有两种方法可以解决这个问题。

1)在类定义中隐式内联构造函数的定义。修改现有的标头代码,以在初始化列表中调用相应的QMainWindow构造函数。并从.cpp文件中删除构造函数定义:

// in test.h
test(QWidget* parent = 0) : QMainWindow(parent), control(device, 0) 
{
  ui.setupUi(this);    
  device.start();  
  control.start();
}

2)在标题中声明构造函数,并在.cpp

中定义它
// in test.h
test(QWidget* parent = 0); // declaration, no definition

// in test.cpp
test::test(QWidget* parent = 0) : QMainWindow(parent), control(device, 0) 
{
  ui.setupUi(this);    
  device.start();  
  control.start();
}

这些解决方案都应该有效。你不能拥有的是两者的结合,这是你的代码样本所展示的。

您可能还需要test::~test()的定义。在您的代码示例中,您只显示声明。

答案 1 :(得分:2)

您有两个主要问题:

1)您应该编写此构造函数,将构造函数的定义留在后面的标题中。

您遇到了提供的两个定义的陷阱,一个位于标题中,另一个位于源文件中。

您需要在标头中包含声明,在源中使用定义,或在标头中包含声明和定义。您不能在标题和源文件中分配一个声明和两个定义!

您在标头中有{}的空定义,而源文件中的另一个定义为{ .... }。编译器如何知道您真正想要哪一个?它不可靠......即使它拿起任何一个版本。

2)另外,你的testControl析构函数似乎是私有的。这不是一个好主意。将析构函数更改为public!

test.h

#pragma once

#include <QtWidgets/QMainWindow>
#include "ui_test.h"
#include "testDevice.h"
#include "testControl.h"

class test : public QMainWindow
{
    Q_OBJECT

public:
    // Only declare, do not define it here
    // Also, for completeness: you should use the "explicit" keyword in here.
    explicit test(QWidget *parent = 0);
    ~test();

private:
    Ui::testClass ui;
    testDevice device;
    testControl control;
};

TEST.CPP

#include "test.h"

test::test(QWidget *parent = 0)
    : QMainWindow(parent)
    , control(device,0)
{
    ui.setupUi(this);    
    device.start();  
    control.start();
}

test::~test()
{
}

testControl.h

#pragma once

#include <QThread>
#include "testDevice.h"

class testControl : public QThread 
{
    Q_OBJECT

public:
    testControl(testDevice& device, QObject *parent = 0);
    // Change this to being _public_ rather than _private_ as in your code.
    ~testControl(void);

protected:
    void run(void);

private:
    testDevice device;
};

答案 2 :(得分:0)

构建类时,也构造所有数据成员。如果存在特定数据成员的默认构造函数,则执行该构造函数。

如果需要执行特定的非默认构造函数,则必须使用成员初始化列表来构造该特定数据成员。

我怀疑你的问题与你的

有关
testDevice device;
testControl control;

数据成员,或两者兼而有之。

这两个类的可用构造函数是什么?如果没有可用的默认构造函数,则必须在成员的初始化列表中初始化它们,并提供适当的参数参数。