0
votes

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

2 Answers

3
votes

Because:

void testFunction(Test in)

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

0
votes

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.