0

Im learning C++ and I ran into something strange that I couldn't find any info on in my C++ book, or on the web. The code below is simply a test of the conversion constructor: Test(int). testFunction gets an int where a Test object is expected, and the conversion constructor is used to create a Test object to send to the function. This works as expected.

#include <iostream> using namespace std; class subClass { public: subClass(int); subClass(subClass&); }; subClass::subClass(int i) {}; subClass::subClass(subClass& i) {}; class Test { public: Test(const Test&); Test(int); subClass sub; }; Test::Test(const Test &) : sub(1) {}; Test::Test(int in) : sub(1) {}; void testFunction(Test in) { cout << "testfunction\n"; }; int main () { testFunction(4); } 

However, If i remove the copy constructor Test(const Test&) from the Test class I get the error message shown below. But the copy constructor is never used, so why is it needed?

example.cpp: In function `int main()': example.cpp:32: error: no matching function for call to `Test::Test(Test)' example.cpp:13: note: candidates are: Test::Test(Test&) example.cpp:24: note: Test::Test(int) example.cpp:32: error: initializing argument 1 of `void testFunction(Test)' from result of `Test::Test(int)' 

Additional info: I noticed that either removing the copy constructor from the subclass or passing the argument by reference to testFunction makes it possible to compile the function without Test's copy constructor. Im using the gnu g++ compiler in cygwin.

2 Answers 2

3

Because:

void testFunction(Test in) 

You're passing a Test object by value which invokes the copy constructor.

Sign up to request clarification or add additional context in comments.

4 Comments

Adding a line to print output from the copy constructor shows that it's not being called.
@snowape That is probably because at code generation time, the copy constructor is being elided because of return value optimization. RVO does not however change the fact that a copy constructor must be available at compilation time. That's my best guess.
Sorry, I didn't really pay attention to main() when answering, I just saw what the error was complaining about. I agree with Michael as to the reason it isn't actually called.
Yes, turning off elision shows that copy constructor is called
0

Another explanation to the question:
If you remove the copy constructor Test(const Test&) from the Test class , you must intend to use compiler-generated copy constructor, which will call subClass sub's copy constructor. But you defined it as subClass(subClass&), which isn't compliant with the convension. So if you change it to subClass(const subClass&), you can remove Test(const Test&) now.

1 Comment

Thanks for the additional info. Now I see how the subclass is involved.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.