0

Question:

Is there a difference between the following initializations?

(A) What exactly is the second one doing?

(B) Is one more efficient than the other?

int variable = 0;
int variable = int();

This question also applies to other data types such as std::string:

std::string variable = "";
std::string variable = std::string();

Background:

I basically got the idea here (the second code sample for the accepted answer) when I was trying to empty out a stringstream. I also had to start using it when I began learning classes and realized that member variable initializations had to be done in the constructor, not just following its definition in the header. For example, initializing a vector:

// Header.h
class myClass
{
 private:
      std::vector<std::string> myVector;
};

// Source.cpp
myClass::myClass()
{
    for (int i=0;i<5;i++)
    {
         myVector.push_back(std::string());
    }
}

Any clarity on this will be greatly appreciated!

Community
  • 1
  • 1
DonDaDev
  • 291
  • 1
  • 2
  • 7
  • 1
    Your two examples are very different because `0` is an `int` but `""` is not a `std::string`, it's a `const char [1]`. – melpomene Aug 29 '15 at 21:00
  • Hmm, well I am still measuring these based on the output that they produce, thank you for insight though. – DonDaDev Aug 29 '15 at 21:07
  • 1
    possible duplicate of [Why use = to initialise a primitive type in C++?](http://stackoverflow.com/questions/353632/why-use-to-initialise-a-primitive-type-in-c) – CIsForCookies Aug 29 '15 at 21:16
  • Just do `myClass::myClass()::myVector(5){}`. This is a X-Y problem. `int i(0);` `int i=0;`; `int i = int();` `int i = int(0)` are equivalent. – user3528438 Aug 29 '15 at 21:16
  • The `int` examples are equivalent, the `std::string` ones could be, depending on how the compiler optimizes the implementation of the ctors receiving no resp. a string literal member. – Deduplicator Aug 29 '15 at 21:24
  • @user3528438 ...and their curly cousins from C++11 as well ;) – Quentin Aug 29 '15 at 21:48
  • @user3528438 not exactly; `int i = int(0)` involves a temporary object but `int i = 0;` doesn't. However, `string s = "";` is exactly the same as `string s = string("");` – M.M Aug 30 '15 at 11:35

2 Answers2

0

Edit

After reading again, I realized that you explicitely asked about the default constructor while I provided a lot of examples with a 1 parameter constructor.

For Visual Studio C++ compiler, the following code only executes the default constructor, but if the copy constructor is defined explicit, it still complains because the never called copy constructor can't be called this way.

#include <iostream>
class MyInt {
public:
    MyInt() : _i(0) {
        std::cout << "default" << std::endl;
    }
    MyInt(const MyInt& other) : _i(other._i) {
        std::cout << "copy" << std::endl;
    }
    int _i;
};
int main() {
    MyInt i = MyInt();

    return i._i;
}

Original (typo fixed)

For int variables, there is no difference between the forms.

Custom classes with a 1 argument constructor also accept assignment initialization, unless the constructor is marked as explicit, then the constructor call Type varname(argument) is required and assignment produces a compiler error.

See below examples for the different variants

class MyInt1 {
public:
    MyInt1(int i) : _i(i) { }
    int _i;
};
class MyInt2 {
public:
    explicit MyInt2(int i) : _i(i) { }
    int _i;
};
class MyInt3 {
public:
    explicit MyInt3(int i) : _i(i) { }
    explicit MyInt3(const MyInt3& other) : _i(other._i) { }
    int _i;
};
int main() {
    MyInt1 i1_1(0); // int constructor called
    MyInt1 i1_2 = 0; // int constructor called

    MyInt2 i2_1(0); // int constructor called
    MyInt2 i2_2 = 0; // int constructor explicit - ERROR!
    MyInt2 i2_3 = MyInt2(0); // int constructor called

    MyInt3 i3_1(0); // int constructor called
    MyInt3 i3_2 = 0; // int constructor explicit - ERROR!
    MyInt3 i3_3 = MyInt3(0); // int constructor called, copy constructor explicit - ERROR!
}
grek40
  • 13,113
  • 1
  • 24
  • 50
-3

The main difference between something like: int i = int(); and int i = 0; is that using a default constructor such as int() or string(), etc., unless overloaded/overridden, will set the variable equal to NULL, while just about all other forms of instantiation and declarations of variables will require some form of value assignment and therefore will not be NULL but a specific value.

As far as my knowledge on efficiency, neither one is "better".

m_callens
  • 6,100
  • 8
  • 32
  • 54
  • 3
    What has `NULL` to do with anything here? Also see http://stackoverflow.com/questions/7200674/is-null-defined-as-nullptr-in-c11, setting an `int` to `NULL` can be an error. – Deduplicator Aug 29 '15 at 21:08
  • "int variable = int()" outputs 0. – DonDaDev Aug 29 '15 at 21:09
  • `int i = int(); bool b = (i == NULL); cout << b << endl;` prints out 1, true. – m_callens Aug 29 '15 at 21:12
  • 1
    @m_callens: Did you look at the post I linked? The most you can say is "seems to work *for you*", because it's semantically broken, the standard does not guarantee it compiles, and there are better implementations where it does not. – Deduplicator Aug 29 '15 at 21:17
  • @m_callens `NULL` is a macro defined to `0` – M.M Aug 30 '15 at 11:36
  • @MattMcNabb No it is a macro that is defined to be `(void*)0`. You can assign it to int in C, but C++ will give warning. – SwiftMango Aug 31 '15 at 03:14
  • @texasbruce sorry but you are just wrong; the C++ standard defines that `NULL` is a macro for an integer literal with value zero. See C++14 [support.types]/3 and [conv.ptr]/1 for the exact text. – M.M Aug 31 '15 at 03:23
  • @MattMcNabb Well try it yourself. – SwiftMango Sep 01 '15 at 02:58
  • @texasbruce the C++ standard is more authoritative than a compiler. If your C++ compiler gives an error for `int x = NULL;` then the compiler is broken (and, after checking you were invoking it in standard mode, you could report a bug). – M.M Sep 01 '15 at 05:05