-1

I am confused how can we pass an integer when the parameter of a function only accept a class of type enemy ( void foo(const Enemy& inKlep ). Yet when we pass to it an int (300) it compiles. Why is this?

#include <iostream>
using namespace std;
class Enemy {
 public:
 Enemy() { cout << "E ctor" << endl; }
 Enemy(int i) { cout << "E ctor " << i << endl; }
 Enemy(const Enemy& src) {cout << "E copy ctor"<< endl;}
 Enemy& operator=(const Enemy& rhs) {cout<<"E="<<endl;}
 virtual ~Enemy() { cout << "E dtor" << endl; }
 void hornet(int i=7) const { // Not virtual!
 cout << "E::hornet " << i << endl;
 }
};
class Scott : public Enemy {
 public:
 Scott() : Enemy(1) { cout << "S ctor" << endl; }
 Scott& operator=(const Scott& rhs) {cout<<"S="<<endl;}
 virtual ~Scott() { cout << "S dtor" << endl; }
 void hornet(int i=7) const {
 cout<<"S::hornet " << i << endl;
 }
};
void foo(const Enemy& inKlep) {
 Enemy theEnemy;
 inKlep.hornet(2);
}
int main(int argc, char** argv) {

 foo(300);
 cout << "Done!" << endl; // Don't forget me!
}
halfer
  • 19,824
  • 17
  • 99
  • 186
ZAX9732
  • 85
  • 6

1 Answers1

3

In C++, it is valid code for an input parameter to implicitly construct an object if the function expects an object that can be constructed from that parameter. So, for example:

struct CustomInt {
    int val;
    CustomInt() : CustomInt(0) {}
    CustomInt(int value) : val(value) {}
};

void func(CustomInt obj) {
    std::cout << obj.val << std::endl;
}

int main() {
    func(5); //Valid; will print '5' to the console
}

If you don't want to allow this, you need to add the keyword explicit to the constructor to prevent this.

struct CustomInt {
    int val;
    CustomInt() : CustomInt(0) {}
    explicit CustomInt(int value) : val(value) {}
};

void func(CustomInt obj) {
    std::cout << obj.val << std::endl;
}

int main() {
    //func(5); //Invalid; will cause a compile-time error
    func(CustomInt(5)); //Valid; will print '5' to the console
}
Xirema
  • 19,889
  • 4
  • 32
  • 68