追加到 QList<QFile*>

Appending onto QList<QFile*>

本文关键字:QFile gt lt QList 追加      更新时间:2023-10-16

我想知道为什么当你制作QFIle的QList时,你必须让它们成为指针。例如,我有一个类,它有一个QList<Q文件*>:

class Files
{
public:
void AddFile(QString newFile);
private:
QList<QFile*> files;
}

现在,当调用AddFIle时,它会执行以下操作:

QFile* newt = new QFile(new_File);
files += newf;

为什么我不能更改QList<QFile**到QList<Q文件>?每次我尝试这样做时,我都会得到一个错误:

QFIle::QFIle(const QFIle&)是私有的

以下是当我将代码更改为QList<Q文件>:

class Files
{
public:
void AddFile(QString newFile);
private:
QList<QFile> files;
}

然后.cpp

QFile newt(new_File);
files += newf;

在您的示例中,QFile类型必须用作*QFile,因为作者将复制构造函数设置为私有的。QList类型需要访问其模板参数的复制构造函数。无法访问QFile的复制构造函数,但QFile*类型具有可访问的复制构造函数。

这很可能是故意的。复制QFile对象可能是不安全的。

简单回答:由于复制QFile对象是危险的,作者使其无法复制(通过使复制构造函数私有)。

长答案:

  1. Qt对QObjects的内部处理:大多数非平凡的Qt对象都是堆生成的,其中许多对象都有特殊的内部变量,如果使用得当,它们的内存(以及生命和引用)可以由Qt内部管理。因此,处理Qt对象的首选方式是作为指针。Qt提供多个智能指针以便于使用。

  2. 一般的资源处理:另一个原因是,即使没有Qt的内部结构,在不使用句柄的情况下共享资源对象的副本也是个坏主意。

这真的很简单:QList有点"不足",因为它只支持可复制的对象。QObjects是不可复制的。QFile是一个QObject。仅此而已。

C++11的std::list支持QObject

如果你使用C++11,并且有一个支持就地构建的容器,不需要复制也不需要默认构建它所包含的对象,那么你当然可以在其中存储对象实例

#include <QFile>
#include <QDir>
#include <list>
int main()
{
std::list<QFile> files;
files.emplace_back(QDir::homePath() + QDir::separator() + "test.txt");
files.front().open(QIODevice::WriteOnly);
files.front().write("abcdefn");
}

为什么QFile不可复制

想想QObject必须做什么,然后想想副本的语义是什么。确保你已经考虑了线程、信号和插槽。然后你会意识到,几乎每个想复制QObject的人都会对这样一个QObject副本的作用提出不同的语义。因此,它实际上是无用的,因为人们通常会忽略文档,因此会有很多错误。我了解自己,因为我曾经修改过自己的Qt副本,允许复制QObject。最终,除了最琐碎的情况外,它在任何情况下都会适得其反。现在我们不要忘记,我们只讨论了QObject复制的语义。

不要忘记,QFile是一个QIODevice,因此它有内部缓冲区。现在告诉我你期望这段代码产生什么:

QFile foo("file");
foo.open(QIODevice::WriteOnly);
foo.write("foo");
QFile bar(foo);
bar.write("bar");
bar.close();
foo.close();

现在假设您已经更改了close()调用的顺序:

bar.close();
foo.close();

这只是为了写作。现在假设我们有这样的代码:

QTcpSocket socket;
socket.connectToHost("localhost", 8080);
socket.waitForConnected(); // do not use it in production code!!
QTcpSocket socket2(socket);
qDebug() << socket.read(3);
qDebug() << socket2.read(3);

考虑到连接的另一端已经发送了"abcdef",您希望得到什么输出是什么?

换句话说:你不希望能够复制一个QIODevice。