My Concern is touching the subject given in the title.
Suppose we have got some very simple class
class Integer{
public:
Integer(int number) : m_value(number) {}
int value(){return m_value;}
private:
int m_value;
};
Now we can use this class, that represents int, of course there is no bigger sense in using this class, but it's just an example. If want this class to behave more like a real integer, then we should provide casting operators (not mentioning operator ==, >, < etc.) and here is my concern, because I can define two operators:
operator T() {return m_value;}
operator T&() {return m_value;}
some easiest examples compiles and works as such with both of them (first or second), so our class can be as follows:
class Integer{
public:
Integer(int number) : m_value(number) {}
int value(){return m_value;}
operator T(){return m_value;} // casting operator
private:
int m_value;
};
But it can be:
class Integer{
public:
Integer(int number) : m_value(number) {}
int value(){return m_value;}
operator T&(){return m_value;} // casting operator
private:
int m_value;
};
As well, so my question is which of those two are appropriate? Of course I cannot have both of them, because compiler would not be able to recongnize which one to use.
Naturally reference casting seems to be more effective, but I am not sure if it would work always the way it should work. Could please advice me somehow and say, why one operator is better than another?
As a matter of fact, you need both and with a bit of tweaking, the compiler will know which to choose. All the magic is in the fact that you can (and should, when it makes sense) define a member function to be const
, id est being callable from a constant object.
Hence, your Integer
class should look like
class Integer
{
public:
Integer() : Integer(0) {}
Integer(int number) : m_value(number) {}
Integer(const Integer& other) : m_value(other.value()) {}
int value() const { return m_value; }
operator int() const { return m_value; }
operator int&() { return m_value; }
const Integer& operator=(const Integer& other) { m_value = other; return *this; }
private:
int m_value;
};
This definition would allow the Integer
class to be usable in those following cases:
#include <iostream>
int main()
{
const Integer zero;
const Integer one(1);
Integer counter;
counter = zero + one;
std::cout << "counter: " << counter << std::endl;
counter++;
std::cout << "counter: " << counter << std::endl;
for (Integer i=0 ; i < counter ; ++i)
{
std::cout << "i: " << i << std::endl;
}
return zero;
}
Compile & run: g++ -std=c++14 -O2 -Wall -pedantic -pthread main.cpp && ./a.out
Output:
counter: 1
counter: 2
i: 0
i: 1
Live example: http://coliru.stacked-crooked.com/a/641fe02e70c02920
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With