gpt4 book ai didi

c++ - 将类声明放在 .cpp 文件中

转载 作者:IT老高 更新时间:2023-10-28 21:55:31 24 4
gpt4 key购买 nike

是否可以在同一个 .cpp 文件中进行类声明和实现?

我想在模拟对象的帮助下进行一些单元测试。这是我的一些测试示例:

// Some includes removed

#include "abstractconnection.h"

class ConnectionMockup : public AbstractConnection
{
Q_OBJECT
public:
explicit ConnectionMockup(QObject *parent = 0);

bool isReady() const;
void sendMessage(const QString &message);

void test_send_message(const QString &message);

bool ready;
QStringList messages;
};

ConnectionMockup::ConnectionMockup(QObject *parent)
: AbstractConnection(parent)
{
ready = true;
}

bool ConnectionMockup::isReady() const
{
return ready;
}

void ConnectionMockup::sendMessage(const QString &message)
{
messages.append(message);
}

void ConnectionMockup::test_send_message(const QString &message)
{
emit messageRecieved(message);
}

TestEmcProgram::TestEmcProgram(QObject *parent) :
QObject(parent)
{
}

void TestEmcProgram::open()
{
ConnectionMockup mockup;
EmcProgram program(&mockup);
QCOMPARE(...
...
...

如您所见,ConnectionMockup 类仅由 TestConnection 类使用,我在其他任何地方都不需要它。因此,当我尝试编译此程序时,出现以下错误:

> testemcprogram.o: In function  
> `ConnectionMockup':
> /home/sasa/Desktop/QtPro/FocoKernel-build-desktop/../FocoKernel/testemcprogram.cpp:29:
> undefined reference to `vtable for
> ConnectionMockup'
> /home/sasa/Desktop/QtPro/FocoKernel-build-desktop/../FocoKernel/testemcprogram.cpp:29:
> undefined reference to `vtable for
> ConnectionMockup' testemcprogram.o: In
> function `~ConnectionMockup':
> /home/sasa/Desktop/QtPro/FocoKernel-build-desktop/../FocoKernel/testemcprogram.cpp:14:
> undefined reference to `vtable for
> ConnectionMockup'

是否可以在这里留下声明,或者我必须创建头文件并将声明移动到该文件中?

编辑: 由于 Jerry Coffin 先生(谢谢 Coffin 先生)建议我可能没有实现一些虚函数,我将在这里声明 AbstractConnection 以便我们可以审查这种可能性:

#include <QObject>

class AbstractConnection : public QObject
{
Q_OBJECT
public:
explicit AbstractConnection(QObject *parent = 0);
virtual ~AbstractConnection();

virtual bool isReady() const = 0;

signals:
void messageRecieved(const QString &message);

public slots:
virtual void sendMessage(const QString &message) = 0;

};

解决方案:感谢@JCooper、@iammilind 和@Jerry Coffin,我们有了解决方案。从 AbstractConnection 中删除析构函数(因为它实际上什么都不做)并从 ConnectionMockup 中删除 Q_OBJECT 后,它就可以工作了。

最佳答案

Q_OBJECT 宏声明了一组元对象成员函数。 MOC 构建工具负责解析 .h 文件并定义这些函数声明。请注意,它不解析 .cpp 文件。在您的情况下,找不到 vtable 因为 MOC 工具没有解析您的 .cpp 文件。解决方案是将您的类定义移动到头文件中,并将头添加到您的 .pro 文件中。第二种解决方案 - 有点“hacky” - 是执行以下操作:

#include <QObject>
#include <QtDebug>

class Counter : public QObject
{
Q_OBJECT

public:
Counter() { value = 0; }
int getValue() const { qDebug() << "getValue()"; return value; }

public slots:
void setValue(int value);

signals:
void valueChanged(int newValue);

private:
int value;
};

#include "main.moc"

void Counter::setValue(int value)
{
qDebug() << "setValue()";
if (this->value != value) {
this->value = value;
emit valueChanged(value);
}
}

int main()
{
Counter a, b;

QObject::connect(
&a, &Counter::valueChanged,
&b, &Counter::setValue);

a.setValue(12);
b.setValue(48);

return 0;
}

注意类定义下的`#include "myfile.moc"。

这是可行的,因为 qmake 将在任何带有#include 指令的文件上调用 MOC 工具。因此,MOC 将解析 .cpp 文件并生成元对象函数定义,从而解决您的链接器错误。

关于c++ - 将类声明放在 .cpp 文件中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5657528/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com