我来自Java背景,最近决定尝试创建一个“有趣”的C ++ Qt GUI应用程序。我一直在努力解决Java和Java之间的许多细微差别。 c ++,但我学到了很多东西。
我试图在我的C ++编码中尽可能地匹配“java风格”语法。虽然这可能是也可能不是C ++的“最佳实践”,但我觉得在学习保持熟悉的时候会有所帮助。一致的语法。其中一个java语法残留是:
//Java
MyObject o = new MyObject();
//C++
MyObject o = MyObject();
现在,我理解C ++有上面的语法快捷方式:
//C++
MyObject o();
这很好,但正如我所说,我不想使用不同的语法。一切都很好,但是当我尝试下面的Qt代码时,我收到了一个惊喜:
QString filepath = "C:\\somefile";
QFile file = QFile(filepath);
收到编译错误:
c:\QtSDK\Desktop\Qt\4.7.2\mingw\include/QtCore/qfile.h:195: error: 'QFile::QFile(const QFile&)' is private within this context
我阅读了Qt文档并发现确实没有公共构造函数QFile :: QFile(const QFile&)。我的代码以前用于其他类的地方,有这样的构造函数。我可以在这里猜一下并说出这句话:
QFile file = QFile(filepath);
实际上正在调用两个构造函数。有人可以解释一下吗?
答案 0 :(得分:7)
//Java
MyObject o = new MyObject();
//C++
MyObject o = MyObject();
这些不等效。 c ++版本创建了一个新对象, on stack ,java只能用原始类型做。一旦o
超出范围,它将被破坏。上面实际发生的是逻辑MyObject o(MyObject());
(不正确的实际语法) - 构造后跟复制构造。
MyObject * o = new MyObject();
这与你的java版本一样接近。当然,需要注意的是,在C ++中你还需要delete o;
- 它不会被垃圾收集。
QFile file = QFile(filepath);
这会在堆栈上再次创建一个临时QFile,然后通过从临时文件中复制构造它来创建file
。它相当于QFile file(QFile(filepath));
。在你的情况下这不起作用,QFile不允许复制构造,所以你需要通过直接构建QFile来避免临时,
// on stack:
QFile file(filepath);
//or in heap:
QFile * file = new QFile(filepath);
答案 1 :(得分:4)
MyObject o();
这不是任何类型的对象声明的捷径。它是一个名为o
的函数的声明,它按值返回MyObject
。
这是对象的最简单声明。如果对象具有用户声明的构造函数,则将调用默认构造函数。
MyObject o;
对于某些基本对象类型(那些是或直接包含POD - 普通旧数据 - 子对象并且没有用户声明的构造函数),可能会对部分或全部对象进行初始化。要确保初始化此类对象的所有部分,您可以从值初始化临时复制初始化。对于具有用户声明的构造函数的对象,这不是必需的。
MyObject o = MyObject();
new
仅在C ++中需要,其中对象需要比创建它的范围更长。 new
始终返回指向动态分配对象的指针。在大多数生产代码中,您通常应立即将此类对象分配给智能指针(例如shared_ptr
),以确保不会泄漏动态分配的对象。
答案 2 :(得分:2)
当您声明这样的对象时:
QFile file = QFile(filepath);
您首先调用带有字符串的构造函数(QFile(filepath)
),然后调用复制构造函数(QFile(const QFile&)
)(通过=
)。
Qt决定将QFile
的复制构造函数设为私有,以防止您复制它。
答案 3 :(得分:1)
QFile file(filepath);
可以正常工作,因为它会调用QFile(const QString&)
构造函数。
在执行QFile file = x
时,file
对象是使用应用于x
的复制构造函数构造的,这是私有的,正如编译器告诉你的那样。
MyClass c(something)
语法不是 MyClass c = something
的快捷方式。第二个将始终调用复制构造函数,第一个将根据something
的类型调用合适的构造函数。
答案 4 :(得分:1)
是
QFile file = QFile(filepath);
创建并构造一个QFile(=右边的那个)。然后,将其分配给另一个QFile。这会在QFile上调用复制构造函数,但正如错误所说,在QFile中已经将其定义为私有,因此您编写的内容将无效。
您可能想要做的是直接创建QFile,如下所示:
QFile file(filepath);
顺便说一句,我认为你的目标是尝试用类似Java的语法编写C ++是错误的!使用C ++,Java或任何语言的程序员已经开发出了以与其他语言不同的语言编写代码的风格。通常原因是使用这些样式可以编写简洁的代码,避免错误和不良的副作用。