Automatic Casting of Integer to an Arbitrary Object

Hi Everyone,

I have been using C++ for many years. Recently I faced a very strange issue for which I couldn't find any explanation. Consider the following example:

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
#include <iostream>

using namespace std;

class test {
        private:
                int x;
        public:
                test(const int y) {
                        x = y;
                }

                void foo() {
                        cout << x << endl;
                }

                ~test() {
                }
};

int main() {
        test a(100);
        test b = 10;
        a.foo();
        b.foo();
        return 0;
}


I expect the compiler not to accept the second line in the main function (test b = 10;) while it accepts. Indeed, it casts the integer (10) to an object of type test constructed as test(10). This is of course because test has a constructor of type test(const int).

However, logically this should not happen. The object of type "test" can be a much more complicated object than a simple integer and casting the integer in this way is meaningless.

I was wondering why this happens and more importantly how one can prevent the compiler from this stupid automatic casting?

Thanks in advance,
explicit
It's not casting an integer to an object of type test, it's constructing b using the provided constructor. Try:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
class test {
        private:
                int x;
        public:
                test(const int y) {
						cout << "y = " << y << endl;
                        x = y;
                }
				
				test & operator=(const test & rhs)
				{
					cout << "Assignment" << endl;
					x = rhs.x;
					return *this;
				}

                void foo() {
                        cout << x << endl;
                }

                ~test() {
                }
};


You'll notice the assignment operator is never called. When you declare an object and assign it in the same expression, it doesn't first construct the default object and then assign, it constructs using the right hand side as the parameter for the constructor.

Change
test b = 10
to
1
2
test b;
b = 10;


And you'll get an error that you don't have a default constructor. Fix that, and THEN you will see the problem you think you are seeing now - "10" will be used to automatically construct a test object when the compiler tries to call "test & operator=(const test & rhs)". It's not exactly 'casting' to an object of type test, but similar. As abramus pointed out, specifying your constructor as being explicit will prevent this behavior.

Last edited on
Thanks a lot Abramus. It solved my problem!
Topic archived. No new replies allowed.