Bjarne wrote:-
For a type T, T() is the notation for the default value , as defined by the default constructor .
What happen when we don't declare default constructor ? For example
using namespace std;
class date{
int n,m;
public:
int day(){return n;}
int month(){return m;}
};//no default constructor
int main()
{
date any =date();
cout<<any.month()<<endl;
cout<<any.day()<<endl;
return 0;
}
Output of this program is 0 and 0 every time i run my program. I haven't declare any default constructor then why there exits a default value i.e. 0?
EDIT-
class date{
int n,m;
public:
date (){
m=1;}
int day(){return n;}
int month(){return m;}
};
int main()
{
date any =date();
cout<<any.month()<<endl;
cout<<any.day()<<endl;
return 0;
}
After reading answers i provide a default constructor but now n is getting garbage value but according to answers it should be 0 as m is out of reach of any other constructor and it is value initialisation as mentioned in answer
The behavior you see is Well-Defined for your class.
How & Why is the behavior Well-Defined?
The rule is:
If you do not provide a no argument constructor the compiler generates one for your program in case your program needs one.
Caveat:
The compiler does not generate the no argument constructor if your program defines any constructor for the class.
As per the C++ Standard an object can be initialized in 3 ways:
Zero Initialization
Default Initialization &
Value Initialization
When, a type name or constructor initializer is followed by () the initialization is through value initialization.
Thus,
date any =date();
^^^
Value Initializes an nameless object and then copies it in to the local object any,
while:
date any;
would be a Default Initialization.
Value Initialization gives an initial value of zero to members that are out of reach of any constructor.
In your program, n and m are beyond the reach of any constructor and hence get initialized to 0.
Answer to Edited Question:
In your edited case, your class provides a no argument constructor, date(), which is capable(& should) initialize members n and m, but this constructor doesn't initialize both the members, So In this case no zero initialization takes place, and the uninitialized members in the object have an Indeterminate(any random) value, further this temporary object is copied to any object which displays the shows indeterminate member values.
For Standerdese Fans:
The rules for object Initialization are aptly defined in:
C++03 Standard 8.5/5:
To zero-initialize an object of type T means:
— if T is a scalar type (3.9), the object is set to the value of 0 (zero) converted to T;
— if T is a non-union class type, each nonstatic data member and each base-class subobject is zero-initialized;
— if T is a union type, the object’s first named data member is zero-initialized;
— if T is an array type, each element is zero-initialized;
— if T is a reference type, no initialization is performed.
To default-initialize an object of type T means:
— if T is a non-POD class type (clause 9), the default constructor for T is called (and the initialization is ill-formed if T has no accessible default constructor);
— if T is an array type, each element is default-initialized;
— otherwise, the object is zero-initialized.
To value-initialize an object of type T means:
— if T is a class type (clause 9) with a user-declared constructor (12.1), then the default constructor for T is called (and the initialization is ill-formed if T has no accessible default constructor);
— if T is a non-union class type without a user-declared constructor, then every non-static data member and base-class component of T is value-initialized;
— if T is an array type, then each element is value-initialized;
— otherwise, the object is zero-initialized
Because compiler, cursing under its breath, generates one for you.
EDIT: Since Als said it does not answer question, I'll elaborate. When you use date any = date();, you call compiler-generated default constructor. This constructor calls default constructors for all base classes and data members. For your data members int default constructor is int(), which sets value to 0. Here is code on ideone.com
#include <iostream>
int main( void )
{
int i = -123;
i = int();
std::cout << i << std::endl;
return( 0 );
}
Program output:
0
From the C++ draft standard (December 1996 Working Paper):
If there is no user-declared constructor for class X, a default constructor is implicitly declared. An implicitly-declared default constructor is an inline public member of its class.
Related
I don't understand how C++11 brace initialization rules work here.
Having this code:
struct Position_pod {
int x,y,z;
};
class Position {
public:
Position(int x=0, int y=0, int z=0):x(x),y(y),z(z){}
int x,y,z;
};
struct text_descriptor {
int id;
Position_pod pos;
const int &constNum;
};
struct text_descriptor td[3] = {
{0, {465,223}, 123},
{1, {465,262}, 123},
};
int main()
{
return 0;
}
Note, that the array is declared to have 3 elements, but only 2 initializers are provided.
However it compiles without error, which sounds strange, as the last array element's reference member will be uninitialized. Indeed, it has NULL value:
(gdb) p td[2].constNum
$2 = (const int &) #0x0: <error reading variable>
And now the "magic": I changed Position_pod to Position
struct text_descriptor {
int id;
Position_pod pos;
const int &constNum;
};
becomes this:
struct text_descriptor {
int id;
Position pos;
const int &constNum;
};
and now it gives the expected error:
error: uninitialized const member ‘text_descriptor::constNum'
My question: Why it compiles in the first case, when it should give an error (as in the second case).
The difference is, that Position_pod uses C - style brace initialization and Position uses C++11 - style initialization, which call Position's constructor. But how does this affect the possibility to leave a reference member uninitialized?
(Update)
Compiler:
gcc (Ubuntu 4.8.2-19ubuntu1) 4.8.2
It will be clear that
struct text_descriptor td[3] = {
{0, {465,223}, 123},
{1, {465,262}, 123},
};
is list-initialisation, and that the initialiser list is not empty.
C++11 says ([dcl.init.list]p3):
List-initialization of an object or reference of type T is defined as follows:
If the initializer list has no elements and T is a class type with a default constructor, the object is value-initialized.
Otherwise, if T is an aggregate, aggregate initialization is performed (8.5.1).
...
[dcl.init.aggr]p1:
An aggregate is an array or a class (Clause 9) with no user-provided constructors (12.1), no brace-or-equal-initializers for non-static data members (9.2), no private or protected non-static data members (Clause 11), no base classes (Clause 10), and no virtual functions (10.3).
td is an array, so it is an aggregate, so aggregate initialisation is performed.
[dcl.init.aggr]p7:
If there are fewer initializer-clauses in the list than there are members in the aggregate, then each member not explicitly initialized shall be initialized from an empty initializer list (8.5.4).
This is the case here, so td[2] is initialised from an empty initialiser list, which ([dcl.init.list]p3 again) means it is value-initialised.
Value-initialisation, in turn, means ([dcl.init]p7):
To value-initialize an object of type T means:
if T is a (possibly cv-qualified) class type (Clause 9) with a user-provided constructor (12.1), ...
if T is a (possibly cv-qualified) non-union class type without a user-provided constructor, then the object is zero-initialized and, if T's implicitly-declared default constructor is non-trivial, that constructor is
called.
...
Your class text_descriptor is a class with no user-provided constructor, so td[2] is first zero-initialised, and then its constructor is called.
Zero-initialisation means ([dcl.init]p5):
To zero-initialize an object or reference of type T means:
if T is a scalar type (3.9), ...
if T is a (possibly cv-qualified) non-union class type, each non-static data member and each base-class subobject is zero-initialized and padding is initialized to zero bits;
if T is a (possibly cv-qualified) union type, ...
if T is an array type, ...
if T is a reference type, no initialization is performed.
This is well-defined regardless of text_descriptor's default constructor: it just zero-initialises the non-reference members and sub-members.
Then the default constructor is called, if it is non-trivial. Here's how the default constructor is defined ([special]p5):
A default constructor for a class X is a constructor of class X that can be called without an argument. If there is no user-declared constructor for class X, a constructor having no parameters is implicitly declared
as defaulted (8.4). An implicitly-declared default constructor is an inline public member of its class. A defaulted default constructor for class X is defined as deleted if:
...
any non-static data member with no brace-or-equal-initializer is of reference type,
...
A default constructor is trivial if it is not user-provided and if:
its class has no virtual functions (10.3) and no virtual base classes (10.1), and
no non-static data member of its class has a brace-or-equal-initializer, and
all the direct base classes of its class have trivial default constructors, and
for all the non-static data members of its class that are of class type (or array thereof), each such class has a trivial default constructor.
Otherwise, the default constructor is non-trivial.
So, the implicitly defined constructor is deleted, as expected, but it is also trivial, if pos is a POD type (!). Because the constructor is trivial, it is not called. Because the constructor is not called, the fact that it is deleted is not a problem.
This is a gaping hole in C++11, which has since been fixed. It happened to have been fixed to deal with inaccessible trivial default constructors, but the fixed wording also covers deleted trivial default constructors. N4140 (roughly C++14) says in [dcl.init.aggr]p7 (emphasis mine):
if T is a (possibly cv-qualified) class type without a user-provided or deleted default constructor, then the object is zero-initialized and the semantic constraints for default-initialization are checked, and if
T has a non-trivial default constructor, the object is default-initialized;
As T.C. pointed out in the comments, another DR also changed so that td[2] is still initialised from an empty initialiser list, but that empty initialiser list now implies aggregate initialisation. That, in turn, implies each of td[2]'s members is initialised from an empty initialiser list as well ([dcl.init.aggr]p7 again), so would seem to initialise the reference member from {}.
[dcl.init.aggr]p9 then says (as remyabel had pointed out in a now-deleted answer):
If an incomplete or empty initializer-list leaves a member of reference type uninitialized, the program is ill-formed.
It is unclear to me that this applies to references initialised from the implicit {}, but compilers do interpret it as such, and there's not much else that could be meant by it.
The first version (the one with _pod suffix) still works but gives no error because for the z value, the default value of int is chosen (the 0). Idem for the const int reference.
In the second version, you cannot define a const reference without giving it a value. The compiler gives you an error because later you cannot assign any value to it.
In addition, the compiler you're using plays an important role here, maybe it's a bug, just because you are declaring a class member before an int member.
I have templated gray_code class which is meant to store some unsigned integer whose underlying bits are stored in Gray code order. Here it is:
template<typename UnsignedInt>
struct gray_code
{
static_assert(std::is_unsigned<UnsignedInt>::value,
"gray code only supports built-in unsigned integers");
// Variable containing the gray code
UnsignedInt value;
// Default constructor
constexpr gray_code()
= default;
// Construction from UnsignedInt
constexpr explicit gray_code(UnsignedInt value):
value( (value >> 1) ^ value )
{}
// Other methods...
};
In some generic algorithm, I wrote something like this:
template<typename UnsignedInt>
void foo( /* ... */ )
{
gray_code<UnsignedInt> bar{};
// Other stuff...
}
In this piece of code, I expected bar to be zero-intialized and therefore bar.value to be zero-initialized. However, after having struggled with unexpected bugs, it appears that bar.value is initialized with garbage (4606858 to be exact) instead of 0u. That surprised me, so I went to cppreference.com to see what the line above was exactly supposed to do...
From what I can read, the form T object{}; corresponds to value initialization. I found this quote interesting:
In all cases, if the empty pair of braces {} is used and T is an aggregate type, aggregate-initialization is performed instead of value-initialization.
However, gray_code has a user-provided constructor. Therefore it is not an aggregate thus aggregate initialization is not performed. gray_code has no constructor taking an std::initializer_list so list initialization is not performed either. The value-initialized of gray_code should then follow the usual C++14 rules of value initialization:
1) If T is a class type with no default constructor or with a user-provided default constructor or with a deleted default constructor, the object is default-initialized.
2) If T is a class type without a user-provided or deleted default constructor (that is, it may be a class with a defaulted default constructor or with an implicitly-defined one) then the object is zero-initialized and then it is default-initialized if it has a non-trivial default constructor.
3) If T is an array type, each element of the array is value-initialized.
4) Otherwise, the object is zero-initialized.
If I read correctly, gray_code has an explicitly defaulted (not user-provided) default constructor, therefore 1) does not apply. It has a defaulted default constructor, so 2) applies: gray_code is zero-initialized. The defaulted default constructor seems to meet all the requirements of a trivial default constructor, so default initialization should not happen. Let's have a look then at how gray_code is zero-initialized:
If T is a scalar type, the object's initial value is the integral constant zero implicitly converted to T.
If T is an non-union class type, all base classes and non-static data members are zero-initialized, and all padding is initialized to zero bits. The constructors, if any, are ignored.
If T is a union type, the first non-static named data member is zero-initialized and all padding is initialized to zero bits.
If T is array type, each element is zero-initialized
If T is reference type, nothing is done.
gray_code is a non-union class type. Therefore, all of its non-static data members should be initialized which means that value is zero-initialized. value satisfies std::is_unsigned and is therefore a scalar type, which means that it should be initialized with "the integral constant zero implicitly converted to T".
So, if I read correctly all of that, in the function foo above, bar.value should always be initialized with 0 and it should never be initialized with garbage, am I right?
Note: the compiler I compiled my code with is MinGW_w4 GCC 4.9.1 with (POSIX threads and dwarf exceptions) in case that helps. While I sometimes get garbage on my computer, I never managed to get anything else than zero with online compilers.
Update: It seems to be a GCC bug that the error is mine and not that of my compiler. Actually, when writing this question, I assumed for the sake of simplicity that
class foo {
foo() = default;
};
and
class foo {
foo();
};
foo::foo() = default;
were equivalent. They are not. Here is the quote from the C++14 standard, section [dcl.fct.def.default]:
A function is user-provided if it is user-declared and not explicitly defaulted or
deleted on its first declaration.
In other words, when I got garbage values, my defaulted default constructor was indeed user-provided since it was not explicitly efaulted on its first declaration. Therefore, what happened was not zero initialization but default initialization. Thanks #Columbo again for pointing out the real problem.
So, if I read correctly all of that, in the function foo above,
bar.value should always be initialized with 0 and it should never be
initialized with garbage, am I right?
Yes. Your object is direct-list-initialized. C++14's* [dcl.init.list]/3 specifies that
List-initialization of an object or reference of type T is defined
as follows:
[… Inapplicable bullet points…]
Otherwise, if T is an aggregate, aggregate initialization is performed (8.5.1).
Otherwise, if the initializer list has no elements and T is a class type with a default constructor, the object is value-initialized.
[…]
Your class isn't an aggregate since it has user-provided constructors, but it does have a default constructor. [dcl.init]/7:
To value-initialize an object of type T means:
if T is a (possibly cv-qualified) class type (Clause 9) with either no default constructor (12.1) or a default constructor that
is user-provided or deleted, then the object is default-initialized;
if T is a (possibly cv-qualified) class type without a user-provided or deleted default constructor, then the object is
zero-initialized and the semantic constraints for
default-initialization are checked, and if T has a non-trivial
default constructor, the object is default-initialized;
[dcl.fct.def.default]/4:
A special member function is user-provided if it is user-declared and
not explicitly defaulted […] on its first declaration.
So your constructor is not user-provided, therefore the object is zero-initialized. (The constructor is not called since its trivial)
And finally, in case this was not clear, to zero-initialize an object or reference of type T means:
if T is a scalar type (3.9), the object is initialized to the value obtained by converting the integer literal 0 (zero) to T;
if T is a (possibly cv-qualified) non-union class type, each non-static data member and each base-class subobject is zero-initialized and padding is initialized to zero bits;
[…]
Thus either
Your compiler is bugged
…or your code triggers undefined behavior at some other point.
* The answer is still yes in C++11, though the quoted sections are not equivalent.
This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
What do the following phrases mean in C++: zero-, default- and value-initialization?
Today I came to know about 3 types of initialization in C++:
Zero Initialization
Default Initialization
Value Initialization
I have googled about it but I found no satisfactory results. All I get is a few standards. What I have understood until now is this: in case of value initialization, a data member can get value equal to zero in some cases.
Please elaborate them (standards) with examples. Also please don't just provide the text from the standard.
Thanks
The types of initialization refer to the language grammar. Here are two examples:
T * p1 = new T;
T * p2 = new T();
The object *p1 is default-initialized, and the object *p2 is value-initialized.
The effect of the initialization depends on the type T: 1) If T is a fundamental, then default-initialization does nothing (i.e. the object is left uninitialized), while value initialization equals zero initialization in that case and means the object is set to zero.
2) If T is an aggregate (i.e. class without constructors or destructor or assignment operator), then each element is recursively default- or value-initialized.
3) If T is of class-type and does have user-defined constructors, then both default- and value-initialization cause a call to the default constructor.
Note that member objects of classes with constructors can in turn be default- or value-initialized:
struct Foo {
int x;
int y;
Foo() : x() { }
};
Now when you say Foo a; then a is default-initialized, so the default constructor is called. This in turn causes a.x to be value-, i.e. zero-initialized, while a.y remains default-, i.e. un-initialized.
(Note that it's not really possible to value-initialize an automatic object, though in C++11, brace-initialization may be used to cause value-initialization, as in Foo a{};. (This behaves exactly the same as Foo a; in our example, consequent to the third paragraph.))
This is dealt with in 8.5 Initializers [dcl.init].
Zero Initialization
5/ To zero-initialize an object or reference of type T means:
— if T is a scalar type (3.9), the object is set to the value 0 (zero), taken as an integral constant expression, converted to T. As specified in 4.10, converting an integral constant expression whose value is 0 to a pointer type results in a null pointer
value.
— if T is a (possibly cv-qualified) non-union class type, each non-static data member and each base-class subobject is zero-initialized and padding is initialized to zero bits;
— if T is a (possibly cv-qualified) union type, the object’s first non-static named data member is zeroinitialized and padding is initialized to zero bits;
— if T is an array type, each element is zero-initialized;
— if T is a reference type, no initialization is performed.
Basically, it's equivalent to a memset(&obj, 0, sizeof(objt));, except that it account that the memory representation of a null pointer might not be a 0 value (even though it is represented by a 0 in the language).
// foo.cpp
static char const* p; // p is zero-initialized
// during static initialization
static void init() {
if (!p) { p = new char[500]; } // fine as p has been 0-initialized
}
Note: personally I still prefer to use = nullptr to initialize p, just to make the intent clear...
Default Initialization
6/ To default-initialize an object of type T means:
— if T is a (possibly cv-qualified) class type (Clause 9), the default constructor for T is called (and the initialization is ill-formed if T has no accessible default constructor);
— if T is an array type, each element is default-initialized;
— otherwise, no initialization is performed.
If a program calls for the default initialization of an object of a const-qualified type T, T shall be a class type with a user-provided default constructor.
Or basically, a call to the default constructor, accounting for arrays, at least for classes. The last point is a caveat for built-ins (such as int). Those are simply left as is (with garbage inside).
Default initialization is what is called when you defined a variable but do not initialize it explicitly. It is also what happens to attributes of a class that are not listed in the initializer list. So the caveat for built-ins is quite important to a programmer.
int function() {
int a; // <-- a is default-initialized (which means nothing happens...)
return a; // <-- uses a, so technically undefined behavior
}
struct A { int a; A() {} }; // During the call to A::A(),
// A::a is default-initialized (nothing happens...)
The absence of explicit initialization is a left-over from C. It's normally so for optimization reasons but leads to Undefined Behavior if one attempts to use the value...
Value Initialization
7/ To value-initialize an object of type T means:
— if T is a (possibly cv-qualified) class type (Clause 9) with a user-provided constructor (12.1), then the default constructor for T is called (and the initialization is ill-formed if T has no accessible default constructor);
— if T is a (possibly cv-qualified) non-union class type without a user-provided constructor, then the object is zero-initialized and, if T’s implicitly-declared default constructor is non-trivial, that constructor is called.
— if T is an array type, then each element is value-initialized;
— otherwise, the object is zero-initialized.
An object that is value-initialized is deemed to be constructed and thus subject to provisions of this International Standard applying to “constructed” objects, objects “for which the constructor has completed,” etc., even if no constructor is invoked for the object’s initialization.
It is a mix of both the above, meaning that the following syntax:
template <typename T> T value() { return T(); }
^~~
provides a suitably initialized instance of T whether T is a class type or a built-in type. It's important for templated code to be able to have such a unified syntax.
Note that with C++11, it is also possible to use T{} to achieve the same effect (which helps disambiguates from functions).
I've been wondering about the language in the C++03 specification surrounding object initialization, specifically section 8.5 paragraph 9 which states,
"If no initializer is specified for an object, and the object is of (possibly cv-qualified) non-POD class type (or
array thereof), the object shall be default-initialized; if the object is of const-qualified type, the underlying
class type shall have a user-declared default constructor. Otherwise, if no initializer is specified for a nonstatic
object, the object and its subobjects, if any, have an indeterminate initial value; if the object or any
of its subobjects are of const-qualified type, the program is ill-formed."
I want to pay particular attention to the clause, "Otherwise, if no initializer is specified for a nonstatic
object, the object and its subobjects, if any, have an indeterminate initial value". According to section 8.5 paragraph 5, the definition of a default-initialization falls into three cases:
if T is a non-POD class type (clause 9), the default constructor for T is called (and the initialization is
ill-formed if T has no accessible default constructor)
if T is an array type, each element is default-initialized
otherwise, the object is zero-initialized.
So as I understand it, paragraph 9 is stating that if we have a non-POD class type that does not have an initializer, then it's default constructor would be called. What I'm confused by is what happens in the case of POD-class types ... it seems from the clause I highlighted that there is no mention of a default constructor call being required for POD-class types. Yet if I created a POD-class type like
struct POD_class
{
int a;
int b;
POD_class() { cout << "Default constructor called" << endl; }
};
int main()
{
POD_class test;
return 0;
}
the default constructor of POD_class seems to be called when this code is compiled and run with g++. Therefore, even if POD_class did not have a specific initializer, it seems it was still default-initialized, per case #1 in the definition of default-initialization, because a default constructor for the type was called.
Based on the above scenario, here is my question: For a POD-class, does not default initializing an object as paragraph 9 mentions for non-static POD-classes mean that its default constructor is not called, or that it's simply not zero-initialized?
Your POD_class is in fact not a POD class. A POD class cannot have a user-declared constructor.
Given the following code:
class temp
{
public:
string str;
int num;
};
int main()
{
temp temp1;
temp temp2 = temp();
cout << temp1.str << endl; //Print ""
cout << temp2.str << endl; //Print ""
cout << temp1.num << endl; //Print a rand num
cout << temp2.num << endl; //Print 0
}
What is the different between these two?—
temp temp1;
and
temp temp2 = temp();
temp temp1;
This calls temp's default constructor on the instance called temp1.
temp temp2 = temp();
This calls temp's default constructor on a temporary object, then calls the compiler-generated copy-constructor on temp2 with the temporary object as the argument (this of course assumes that the compiler doesn't elide copies; it depends on your compiler's optimization settings).
As for why you get different initialized values, section 8.5 of the standard is relevant:
8.5 Initializers [dcl.init]
Paragraph 5: To zero-initialize an object of type T means:
if T is a scalar type (3.9), the object is set to the value of 0 (zero) converted to T;
if T is a non-union class type, each nonstatic data member and each base-class subobject is zero-initialized;
if T is a union type, the object’s first named data member is zero-initialized;
if T is an array type, each element is zero-initialized;
if T is a reference type, no initialization is performed.
To default-initialize an object of type T means:
if T is a non-POD class type (clause 9), the default constructor for T is called (and the initialization is ill-formed if T has no accessible default constructor);
if T is an array type, each element is default-initialized;
otherwise, the object is zero-initialized.
To value-initialize an object of type T means:
if T is a class type (clause 9) with a user-declared constructor (12.1), then the default constructor for T is called (and the initialization is ill-formed if T has no accessible default constructor);
if T is a non-union class type without a user-declared constructor, then every non-static data member and base-class component of T is value-initialized;
if T is an array type, then each element is value-initialized;
otherwise, the object is zero-initialized.
Paragraph 7: An object whose initializer is an empty set of parentheses, i.e., (), shall be value-initialized.
Paragraph 9: If no initializer is specified for an object, and the object is of (possibly cv-qualified) non-POD class type (or array thereof), the object shall be default-initialized; if the object is of const-qualified type, the underlying class type shall have a user-declared default constructor. Otherwise, if no initializer is specified for a nonstatic object, the object and its subobjects, if any, have an indeterminate initial value; if the object or any of its subobjects are of const-qualified type, the program is ill-formed.
12 Special Member Functions [special]
Paragraph 7: An implicitly-declared default constructor for a class is implicitly defined when it is used to create an object of its class type (1.8). The implicitly-defined default constructor performs the set of initializations of the class that would be performed by a user-written default constructor for that class with an empty mem-initializer-list (12.6.2) and an empty function body.
12.6.2 Initializing bases and members [class.base.init]
Paragraph 4: If a given nonstatic data member or base class is not named by a mem-initializer-id (including the case where there is no mem-initializer-list because the constructor has no ctor-initializer), then
If the entity is a nonstatic data member of (possibly cv-qualified) class type (or array thereof) or a base class, and the entity class is a non-POD class, the entity is default-initialized (8.5). If the entity is a nonstatic data member of a const-qualified type, the entity class shall have a user-declared default constructor.
Otherwise, the entity is not initialized. If the entity is of const-qualified type or reference type, or of a (possibly cv-qualified) POD class type (or array thereof) containing (directly or indirectly) a member of a const-qualified type, the program is ill-formed.
So now that the rules have been laid out, let's see how they apply:
temp temp1;
temp is a non-POD type (because it has a std::string member), and since no initializer is specified for temp1, it will be default-initialized (8.5/9). This calls the default constructor (8.5/5). temp has an implicit default constructor (12/7) which default-initializes the std::string member and the int member isn't initialized at all (12.6.2/4).
temp temp2 = temp();
On the other hand, the temporary temp object is value-initialized (8.5/7), which value-initializes all data members (8.5/5), which calls the default constructor in the std::string member and zero-initializes the int member (8.5/5).
Of course, if you much rather not have to refer to the standard in 5+ different places, just ensure that you explicitly initialize everything (e.g. int i = 0; or using initializer lists).
The behavior of your code depends critically on the compiler you are using. More precisely, it depends on which version of language specification your compiler implements.
For C++98 compilers, both declarations have identical effect on the final values of the objects being declared: the str member should become empty, while the num members should contain unpredictable value. In both cases the actual initialization is default-initialization performed by a compiler-provided default constructor of class temp. That default constructor initializes str, but leaves num uninitialized.
For C++03 compilers the behavior is different. There's no difference for temp1 object (its num is still unpredictable). But temp2 initialization is handled differently. In C++03 the () initializer triggers the new kind of initialization - so called value-initialization. Value-initialization ignores the compiler-provided default constructor of the top level object, and instead works directly on its subobjects (data members in this case). So the temp2 object is effectively initialized by value-initialization, which also sets the num member to zero (in addition to initializing str with an empty string). For this reason, temp2.num ends up being zero in C++03 compilers.
If in your experiments you observed consistent zero in temp2.num, it means that your compiler follows the C++03 specification in this respect.
temp temp1;
Will create a default initialized temp object. Since you provided no default constructor for temp, every member of temp will be default initialized too. Since std::string provides a default ctor, it gets initialized correctly and has a well-defined value. The integer, however, gets default initialized, which is implementation defined and normally a random value.
temp temp2 = temp();
This will first create a value initialized temp object. This is important, because the object itself is value initialized, so are its members. It doesn't matter for the string, as default and value initialization are the same, but it matters for the integer. A value initialized integer has the value 0.
After that, you just copy over those members into temp2.
Also, this relevant question might be of interest to you.
Edit: See my comment on #In silico's answer for explanation on why this isn't the case for MSVC. :/