附加到QList <qfile *> </qfile *>

时间:2014-02-28 02:21:05

标签: c++ qt raii

我想知道为什么当你制作QFIle的QList时,你必须让它们成为指针。例如,我有一个具有QList&lt; QFile *&gt;:

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

private:
QList<QFile*> files;
}

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

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

为什么我无法更改QList&lt; QFile *&gt;进入QList&lt; QFile&gt;?每当我尝试这样做时,我都会收到错误:

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

以下是我将其更改为QList时的代码示例&lt; QFile&gt;:

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

private:
QList<QFile> files;
}

然后是.cpp

QFile newt(new_File);
files += newf;

3 个答案:

答案 0 :(得分:2)

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

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

答案 1 :(得分:2)

简短回答:因为复制QFile对象很危险,作者无法复制(通过将复制构造函数设为私有)。

答案很长:

  1. Qts的Qt内部处理:大多数非平凡的Qt对象是堆生成的,many of them有特殊的内部变量,当正确使用时,允许它们的内存(以及生命和引用)由Qt内部管理。因此,处理Qt对象的首选方法是作为指针。 Qt提供了多个smart pointers以便于使用。

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

答案 2 :(得分:1)

这很简单: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。

相关问题