这真的很简单:QList 有点“不足”,因为它只支持可复制的对象。 QObjects 是不可复制的。 QFile 是一个 QObject。仅此而已。
C++11 的 std::list 支持 QObject
如果您使用 C++11 并且有一个支持就地构造并且不需要复制或默认构造它所拥有的对象的容器,那么您可以当然将对象实例存储在它。以下适用于 Qt 4 和 Qt 5:
#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("abcdef\n");
}
为什么 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。