I come from a Java background and recently decided to try creating a C++ Qt GUI application "for fun". I've been struggling with many of the finer differences between Java & c++, but I've learned a lot.
I'm attempting to match "java-style" syntax as closely as possible in my C++ coding. While this may or may not be a "best practice" for C++, I feel it helps when learning to keep a familar & consistent syntax. One of the java syntax carryovers is this:
//Java
MyObject o = new MyObject();
//C++
MyObject o = MyObject();
Now, I understand C++ has a syntax shortcut for the above:
//C++
MyObject o();
This is nice and all, but as I said, I don't want to use different syntax, yet. Everything was working fine, but I received a surprise when I attempted the following Qt code:
QString filepath = "C:\\somefile";
QFile file = QFile(filepath);
And got a compile error:
c:\QtSDK\Desktop\Qt\4.7.2\mingw\include/QtCore/qfile.h:195: error: 'QFile::QFile(const QFile&)' is private within this context
I read the Qt docs and discovered that there is indeed no public constructor QFile::QFile(const QFile&). Where my code previously worked for other classes, there was such a constructor. I can make a guess here and say that the line:
QFile file = QFile(filepath);
is actually making calls to two constructors. Can someone explain?
//Java
MyObject o = new MyObject();
//C++
MyObject o = MyObject();
These are not equivalent. The c++ version creates a new object, on stack, something java can only do with primitive types. Once o goes out of scope it will be destructed. What actually happens above is logically MyObject o(MyObject()); (incorrect actual syntax) - construction followed by copy-construction.
MyObject * o = new MyObject();
This is as close as you gets to your java version. The caveat, of course, is that in C++ you'll need to also delete o; - it's not going to get garbage collected.
QFile file = QFile(filepath);
This creates a temporary QFile, again on stack, and then creates file by copy-constructing it from the temporary. It is equivalent to QFile file(QFile(filepath));. In your case this will not work, QFile does not allow copy construction, so you'll need to avoid the temporary by constructing QFile directly,
// on stack:
QFile file(filepath);
//or in heap:
QFile * file = new QFile(filepath);
MyObject o();
This is not a short cut for any type of object declaration. It is a declaration of a function called o returning a MyObject by value.
This is the simplest declaration of an object. If the object has a user-declared constructor then the default constructor will be invoked.
MyObject o;
For some basic object types (those which are or directly contain POD - plain-old-data - subobjects and don't have a user-declared constructor), some or all of the object may be left initialized. To ensure that all parts of such an object are initialized you can copy-initialize from a value initialized temporary. This isn't necessary for objects which do have a user-declared constructor.
MyObject o = MyObject();
new is only require in C++ where an object needs to outlive the scope in which it is created. new always returns a pointer to the dynamically allocated object. In most production code you should normally immediately assign such an object to a smart pointer such as a shared_ptr to ensure that dynamically allocated objects aren't leaked.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With