繁体   English   中英

附加到QList <QFile*>

[英]Appending onto QList<QFile*>

我想知道为什么当您创建QFIle的QList时必须使它们成为指针。 例如,我有一个具有QList <QFile *>的类:

class Files
{
public:
   void AddFile(QString newFile);

private:
QList<QFile*> files;
}

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

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

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

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

当我将其更改为QList <QFile>时,代码如下所示:

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对QObject的内部处理:大多数非平凡的Qt对象都是堆生成的,并且其中许多具有特殊的内部变量,如果使用得当,它们可以由Qt在内部管理其内存(以及寿命和引用)。 因此,处理Qt对象的首选方法是作为指针。 Qt提供了多个智能指针 ,易于使用。

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

这非常简单:QList有点“不足”,因为它仅支持可复制对象。 QObject是不可复制的。 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。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM