Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++ Overloading Conversion Operators

I am trying to have a class that allows implicit casting to certain built in types, like unsigned long int and since I'm trying to do this as correct as possible (this is my first important project in C++), I have hit a strange issue regarding const correctness:

This works:

#include <iostream>

class CustomizedInt
{
private:
    int data;
public:
    CustomizedInt();
    CustomizedInt(int input);
    operator unsigned long int () const
    {
        unsigned long int output;
        output = (unsigned long int)data;
        return output;
    }
};

CustomizedInt::CustomizedInt()
{
    this->data = 0;
}

CustomizedInt::CustomizedInt(int input)
{
    this->data = input;
}

int main()
{
    CustomizedInt x;
    unsigned long int y = x;

    std::cout << y << std::endl;

    return 0;
}

But this:

#include <iostream>

class CustomizedInt
{
private:
    int data;
public:
    CustomizedInt();
    CustomizedInt(int input);
    operator unsigned long int () const;
};

CustomizedInt::CustomizedInt()
{
    this->data = 0;
}

CustomizedInt::CustomizedInt(int input)
{
    this->data = input;
}

CustomizedInt::operator unsigned long()
{
    unsigned long int output;
    output = (unsigned long int)data;
    return output;
}

int main()
{
    CustomizedInt x;
    unsigned long int y = x;

    std::cout << y << std::endl;

    return 0;
}

gives me this error in Visual Studio 2010: error C2511: 'CustomizedInt::operator unsigned long(void)' : overloaded member function not found in 'CustomizedInt'

Now, if I remove the keyword const from the operator definition, everything is OK. Is this a bug? I read that I'm supposed to use the const keyword after each (public) method / operator in order to clearly state that it does not alter the current object in any way.

Also, I know that defining such an operator may be poor practice, but I am not sure I fully understand the associated caveats. Could somebody please outline them? Would it be better practice to just define a public method called ToUnsignedLongInt?

like image 557
Mihai Todor Avatar asked Apr 23 '12 13:04

Mihai Todor


2 Answers

The function signature does not match the function definition.

operator unsigned long int () const;

and

CustomizedInt::operator unsigned long()    { ... }
                                       ^^^
                                   const missing

In this case you should mark the conversion operator as const since it doesn't affect the internal state of the object.

Also, use constructor initialization lists to initialize your member variables.

CustomizedInt::CustomizedInt()
: data()
{
}

CustomizedInt::CustomizedInt(int input)
: data(input)
{
}
like image 80
Praetorian Avatar answered Oct 16 '22 05:10

Praetorian


You could remove the const from the declaration, but what you almost certainly want to do is add it to the definition:

CustomizedInt::operator unsigned long() const
{
    unsigned long int output;
    output = (unsigned long int)data;
    return output;
}
like image 27
Jerry Coffin Avatar answered Oct 16 '22 04:10

Jerry Coffin