我是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作为指针并作为参考,但我还有很多其他错误......有人可以帮我解决这个问题并向我解释发生了什么事吗?
答案 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!
#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;
};
#include "test.h"
test::test(QWidget *parent = 0)
: QMainWindow(parent)
, control(device,0)
{
ui.setupUi(this);
device.start();
control.start();
}
test::~test()
{
}
#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;
数据成员,或两者兼而有之。
这两个类的可用构造函数是什么?如果没有可用的默认构造函数,则必须在成员的初始化列表中初始化它们,并提供适当的参数参数。