Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

c++ Assigning objects in object declaration

Tags:

java

c++

qt

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?

like image 763
gmallett Avatar asked Apr 16 '26 05:04

gmallett


2 Answers

//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);
like image 73
Erik Avatar answered Apr 18 '26 18:04

Erik


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.

like image 27
CB Bailey Avatar answered Apr 18 '26 19:04

CB Bailey



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!