我想知道为什么当你制作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&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;
答案 0 :(得分:2)
在您的示例中,QFile
类型必须用作*QFile
,因为作者将复制构造函数设为私有。 QList
类型需要访问其模板参数的复制构造函数。无法访问QFile
的复制构造函数,但QFile*
类型具有可访问的复制构造函数。
这很可能是故意的。复制QFile
对象可能不安全。
答案 1 :(得分:2)
简短回答:因为复制QFile对象很危险,作者无法复制(通过将复制构造函数设为私有)。
答案很长:
Qts的Qt内部处理:大多数非平凡的Qt对象是堆生成的,many of them有特殊的内部变量,当正确使用时,允许它们的内存(以及生命和引用)由Qt内部管理。因此,处理Qt对象的首选方法是作为指针。 Qt提供了多个smart pointers以便于使用。
一般资源处理:另一个原因是,即使没有Qt的内部结构,在不使用句柄的情况下共享资源对象的副本也是一个坏主意。
答案 2 :(得分:1)
这很简单:QList有点“不足”,因为它只支持可复制对象。 QObject是不可复制的。 QFile
是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");
}
想想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。