This question already has answers here:
What are the basic rules and idioms for operator overloading?
(8 answers)
Closed 6 years ago.
Let's say, I have two simple classes: integer with just one int variable in it, and real with double. I'm already done so that
integer a=2016;
int b=a;
real a=20.16;
double b=a;
working perfectly. Now I have to do the conversion between them, like so:
integer foo; real bar;
foo=bar;
bar=foo;
Or at least with similar syntax. I know that there will be loss of some data when converting double to int, I'll deal with it. So how can I do that? What and where should I #include and what the methods/operator overloads to write? My project is divided into files main.cpp, integer.h, integer.cpp, real.h, real.cpp. Thanks.
EDIT: The classes looks like:
//integer.h
class integer
{
private:
int a;
public:
integer();
integer(int number);
operator int() const;
};
//integer.cpp
#include "integer.h"
integer::integer(){
a=0;
}
integer::integer(int number){
a=number;
}
integer::operator int() const{
return a;
}
//real.h
class real {
private:
double a;
public:
real();
real(double number);
operator double() const;
};
//real.cpp
#include "real.h"
real::real(){
a=0;
}
real::real(double number){
a=number;
}
real::operator double() const{
return a;
}
You basically have two solutions to your problem:
The first is to write conversion operators that can convert a real object to an integer object, and vice versa.
The other solution is to implement custom constructors and assignment operators to take the other class.
Related
I'm new to C++ and I'm trying to understand how Class works. I made a simple example for myself when I encounter this problem. My class has one private property num and I'm trying to initialize it with an int this way: Number one = Number::ONE; but it doesn't work. However, when I do this it works fine: Number one; one = Number::ONE. I prefer the first option. Please help!
Here is my complete code:
class Number {
public:
enum {ONE, TWO, THREE, FOUR};
Number();
void print() const;
Number& operator=(int);
private:
int num;
};
Number& Number::operator=(int n) {
num = n;
return *this;
}
int main(int argc, const char * argv[]) {
Number n = Number::ONE; // doesn't work :(
n.print();
return 0;
}
Number::Number() {
num = 0;
}
void Number::print() const {
cout << num << endl;
}
In C++, when you write
Number one = Number::ONE;
the compiler will not use the assignment operator to initialize one. The operator= function is only invoked when you have an existing object that you want to reassign a new value. Instead, in this case, the compiler tries to invoke a conversion constructor, a constructor that takes in an object of the type on the right-hand side of the equality. Since you haven't defined a constructor like that, you're getting a compiler error.
One way to do this would be something like this:
class Number {
public:
Number(int value); // <-- Conversion constructor
...
};
Number::Number(int value) {
num = value;
}
Now, the code you've given here will compile properly.
You may want to do some reading into copy constructors, assignment operators, conversion constructors, and conversion assignment operators, since they're one of the trickier parts of routine C++ and often trip up people transitioning from basic C++ to more intermediate-level language techniques.
you didn't overload the constructor to take an integer as parameter that is why you get the error:
class Number
{
public:
enum {ONE, TWO, THREE, FOUR};
Number(int x) : num(x){}
void print() const;
Number& operator=(int);
private:
int num;
};
This question already has answers here:
The assignment operator and initialization
(2 answers)
Closed 6 years ago.
I am trying to overload the assignment operator but it doesn't seem to work. The code is based on this answer. I've searched for other examples of overloading the assignment operator, but it doesn't seem like my code shouldn't run.
This is my code:
#pragma once
#include <assert.h>
class ReadOnlyInt
{
public:
ReadOnlyInt(): assigned(false) {}
ReadOnlyInt& operator=(int v);
operator int() const ;
private:
int value;
bool assigned;
};
ReadOnlyInt& ReadOnlyInt::operator=(int v)
{
assert(!assigned);
value = v;
assigned = true;
return *this;
}
ReadOnlyInt::operator int() const
{
assert(assigned);
return value;
}
Intellisense doesn't give any warnings, but the operator= is not highlighted as a keyword.
Now if I make an assigment, Intellisense does recognize it's not possible:
ReadOnlyInt bar = 12;
no suitable constructor exists to convert from "int" to "ReadOnlyInt"
This works however:
int foo = bar;
Solution
This question was marked as duplicate, so I can't answer it. This was the solution I came up with based on the comments and answer on this question:
ReadOnlyInt::ReadOnlyInt()
: assigned(false)
{}
ReadOnlyInt::ReadOnlyInt(int v)
: value(v), assigned(true)
{}
You can't initialize and declare at the same time. You need to do this
ReadOnlyInt bar;
bar = 12;
This is because there is no appropriate constructor for ReadOnlyInt that takes an int argument.
I'm fairly familiar with operator overloading, however I am wondering how do we implement something like this:
myClass myclassobj;
int x;
x = 5;
x = x + myclassobj
There is no way to overload the + operator for the int class, so something should be done from myClass, but how would we do that? I am probably using the wrong keywords, but searching through SO didn't lead to anithing. Apologies if I did something wrong, this is my first post here.
Edit - My class is a custom vector class, so simply converting it to given type won't work.
Define an overloaded operator with the signature int operator+(int, myClass).
You are right.
There is no way to overload the + operator for the int class, so
something should be done from myClass
Your question:
but how would we do that?
My answer:
You should use user defined type conversion. It may work with a conversion operator.
#include <iostream>
class myClass
{
int i;
public:
myClass(int i=0) : i(i) { }
operator int(){ // A conversion from myClass to int may solve your problem.
return i;
}
};
int main()
{
myClass myclassobj(99);
int x=7;
x = 5;
x = x + myclassobj;
std::cout<<x<<std::endl;
return 0;
}
Brian gave a good answer also, but it works only if the overloaded operator does not need protected or private members from the second argument or if overloaded operator declared as friend of myClass.
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 7 years ago.
Improve this question
I have the following problem:
suppose that I'm trying to implement my own class MyInt, which is capable of holding large numbers (I know about BigNum implementation - this is just a practice). I have implemented constructors that accept int, unsigned long, unsigned long long etc. - hence my question.
I'm trying to overload the operator +, with the following declaration:
friend MyInt operator+(const MyInt &, const MyInt &);
inside the class.
It works fine when I'm adding to MyInt's, however I would like it to work in cases like
MyInt x(0);
x = x + 1;
When I call it like that, I get the following output:
error: ambiguous overload for ‘operator+’ (operand types are ‘MyInt’ and ‘int’)
I would appreciate any suggestions on how to solve that
Edit:
Here's sample code, written by me. The constructor is explicit
using namespace std;
class MyInt {
public:
MyInt() {};
explicit MyInt(int) {};
friend MyInt operator+(const MyInt &x, const MyInt &y) {
MyInt result;
cout << "operator + " << endl;
return result;
}
};
int main() {
MyInt x;
x = x + x; //this is fine
x = x + 1; //this is not
}
The construct is explicit, means the implicit conversion from int to MyInt is not allowed, and then operator+(const MyInt &, const MyInt &) couldn't be applied for the call of MyInt + int.
Solution1
Add overload version of operator+, such as:
MyInt operator+(const MyInt &, int);
MyInt operator+(int, const MyInt &);
Solution2
Remove explicit from the constructor.
Given the following problem:
using namespace std;
class MyInt {
public:
MyInt() {};
explicit MyInt(int) {};
friend MyInt operator+(const MyInt &x, const MyInt &y) {
MyInt result;
cout << "operator + " << endl;
return result;
}
};
int main() {
MyInt x;
x = x + x; //this is fine
x = x + 1; //this is not
}
… a reasonable solution is to make the converting constructor implicit, i.e. non-explicit.
For example, std::string allows you to construct a std::string implicitly from a literal. That provides a great practical benefit. But then, there is no problem with s + s because there's no built-in + for pointer arguments, and std::string doesn't provide implicit conversion back to char const*.
Still, I think an implicit conversion to the big-number class makes sense. Make the opposite conversion, to built-in type, explicit (if it's implicit then this problem pops up again). And preferably named.
The solution is to add an operator+(const MyInt & lhs, int rhs);
Another solution is to add a MyInt(int) constructor that is then implicitly called by the compiler.
This question already has answers here:
Non-member conversion functions; Casting different types, e.g. DirectX vector to OpenGL vector
(3 answers)
Closed 8 years ago.
Is it possible using friends?
class MyClass
{
private:
int myInteger;
float myFloat;
public:
void SetData(int a, float b)
{
myInteger = a;
myFloat = b;
}
operator int();
friend operator float(MyClass & );
};
MyClass :: operator int()
{
return myInteger;
}
operator float(MyClass & obj)
{
return obj.myFloat;
}
This code doesn't compile. How to do it in a correct way?
VS2008 says:
error C2801: 'operator float' must be a non-static member
Why not making op float a member?
operator float(){ return myFloat;}
If overloading the operator isn't working for you, consider using a named function:
float ToFloat(MyClass & obj)
{
return obj.myFloat;
}
This will also avoid implicit conversions... but I suppose if you were planning on overloading the operator your intention was to allow the implicit conversion.