Why isn't the constructor of this class being called?

I'm trying to understand an example given in my textbook. According to the answer key for the textbook, the program at the end of my post will display the following (FYI the text explaining is not part of the actual output, just notes from the answer to explain where it comes from):
4 (This line is displayed by constructor #2)
7 (This line is displayed by constructor #1)
2 (This line is displayed by constructor #2)
2 (This line is displayed by the destructor)
7 (This line is displayed by the destructor)
4 (This line is displayed by the destructor)

When I run this code in Visual Studio, I only get the following
4 (Presumably from constructor #2)
2 (Presumably from constructor #2)

Both the constructor and destructors never seem to get called. I think I understand why the destructor isn't called - I have to place a break at return 0 to keep the console terminal open, and I suspect that the object isn't destroyed until main returns 0, and so I don't see the destructor being called. If anyone can confirm this, it'd be appreciated.

Moreover, I'm stumped as to why the constructor never seems to be called so that you see an output of 7 when you create obj2. Does anyone have any thoughts as to why this is the case?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
#include <iostream>
using namespace std;
class Package
	{
	private:
		int value;
	public:
		Package()
		{
			cout << "Now triggering the constructor" << endl;
			value = 7; cout << value << endl;
		}
		Package(int v)
		{
			value = v; cout << value << endl;
		}
		~Package()
		{
			cout << value << endl;
		}
	};

int main()
{
	Package obj1(4);
	Package obj2();
	Package obj3(2);
	return 0;
}
Last edited on
23
24
25
26
27
28
29
30
int main()
{
	Package obj1(4);
	//Package obj2(); // <------ most vexing parse - it's a function declaration
        Package obj2; // calls default constructor
	Package obj3(2);
	return 0;
}


4
Now triggering the constructor
7
2
2
7
4


Good Luck !!
Maybe more obvious like this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
#include <iostream>
using namespace std; //avoid having this
class Package
	{
	private:
		int value;
	public:
		Package()
		{
			cout << "Now triggering default constructor" << endl;
			value = 7; cout << value << endl;
		}
		Package(int v)
		{
		    cout << "Now triggering int constructor" << endl;
			value = v; cout << value << endl;
		}
		~Package()
		{
		   cout << "Now triggering destructor" << endl; 
			cout << value << endl;
		}
	};

int main()
{
	Package obj1(4);
	//Package obj2();
	Package obj2;
	Package obj3(2);
	return 0;
}


Now triggering int constructor
4
Now triggering default constructor
7
Now triggering int constructor
2
Now triggering destructor
2
Now triggering destructor
7
Now triggering destructor
4
Whoa, good eye. I didn't actually even know that Package obj2(); was a function declaration rather than a definition of an object that would trigger the constructor.

This was copied and pasted directly from a textbook - so turns out there's a mistake in the textbook. Starting out with C++ 8th edition, in case anyone's curious.

Thanks for your help.

This was copied and pasted directly from a textbook - so turns out there's a mistake in the textbook.


There are a lot of bad text books out there, get a good one from this list:

http://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list
Heh, wish it was up to me! It's required for my course.
Well that doesn't stop one from reading stuff elsewhere. I guess it matters for the extra expense, but there is also a lot of good stuff on the net, and bad stuff too.

cppreference is a really good site:


http://en.cppreference.com/w/cpp
http://en.cppreference.com/w/cpp/links

StackOverflow is really good too.
At the risk of sounding a little pedantic, that's not the most vexing parse.

The "most vexing parse" is a name for a similar-looking condition involving type decay, where, e.g.,
Foo f(Bar());
Is intended to be a declaration of an instance of Foo named f, constructed with an anonymous instance of Bar. Instead it's a declaration of a function named f returning a Foo and accepting a pointer to function returning a Bar and accepting nothing. Gross. The type decay is implicit in the function-to-pointer conversion in the argument to f.

The way to avoid the issue is to (preferably)
a.) compile with -Wvexing-parse (i.e., with -Wall -Wextra -pedantic-errors); and
b.) use the uniform initialization syntax Foo f{Bar{}};
Alternatively, you may add parentheses around the argument:
Foo f((Bar()));
Last edited on
Topic archived. No new replies allowed.