Object as array index - c++

I have the following class:
class MyInteger
{
private:
__int64 numero;
static __int64 int64Pow(__int64, __int64);
public:
// It doesn't matter how these methods are implemented
friend class MyInteger;
MyInteger(void);
MyInteger(const MyInteger&);
MyInteger(const __int64&);
~MyInteger(void);
static MyInteger const minValue;
static MyInteger const maxValue;
MyInteger& operator = (const MyInteger&);
MyInteger operator + (const MyInteger&) const;
MyInteger operator - (const MyInteger&) const;
MyInteger operator * (const MyInteger&) const;
MyInteger operator / (const MyInteger&) const;
MyInteger& operator += (const MyInteger&);
MyInteger& operator -= (const MyInteger&);
MyInteger& operator *= (const MyInteger&);
MyInteger& operator /= (const MyInteger&);
MyInteger operator % (const MyInteger&) const;
MyInteger& operator %= (const MyInteger&);
MyInteger& operator ++ ();
MyInteger operator ++ (int);
MyInteger& operator -- ();
MyInteger operator -- (int);
bool operator == (const MyInteger&) const;
bool operator != (const MyInteger&) const;
bool operator > (const MyInteger&) const;
bool operator < (const MyInteger&) const;
bool operator >= (const MyInteger&) const;
bool operator <= (const MyInteger&) const;
int toStdInt() const
{
return (int)numero;
}
float toStdFloat() const;
double toStdDouble() const;
char toStdChar() const;
short toStdShortInt() const;
long toStdLong() const;
long long toStdLongLong() const;
unsigned int toStdUInt() const;
__int64 toStdInt64() const;
unsigned __int64 toStdUInt64() const;
unsigned long long int toStdULongLong() const;
long double toStdULongDouble() const;
template<class Type>
Type& operator[](Type* sz)
{
return sz[toStdULongLong()];
}
};
template<class Type>
Type* operator+(const Type* o1, const MyInteger& o2)
{
return ((o1) + (o2.toStdInt()));
}
I'd like to use this class to access array elements like this:
MyInteger myInt(1);
int* intPtr = (int*)malloc(sizeof(int) * N);
intPtr[myInt] = 1;
I thought that the function
template<class Type>
Type* operator+(const Type* o1, const MyInteger& o2)
{
return ((o1) + (o2.toStdInt()));
}
could solve my problem, because as this post reports (Type of array index in C++) "The expression E1[E2] is identical (by definition) to *((E1)+(E2))", but I get the C2677 error ('[' operator: no global operator found which takes type 'MyInteger' (or there is no acceptable conversion))
Can someone clarify me this situation?
Thanks

You may be able to do that by overriding the cast to int of your MyInteger class in a way similar to:
class MyInteger {
...
operator int() const
{
return toStdInt(); /** Your class as an array index (int) */
}
...
}

Related

Binary operator overloading with class and constant in C++

I am trying to do operator overloading
My header is:
class Nyble
{
public:
Nyble();
Nyble(const Nyble& n);
Nyble& operator=(const Nyble& n);
~Nyble();
Nyble operator+(const char a);
Nyble operator-(const char a);
Nyble operator+(Nyble& n1);
Nyble operator+();
unsigned char getData();
private:
// Do not change this data
unsigned char data;
}
Source:
#include "Nyble.h"
unsigned char Nyble::getData()
{
return this->data;
}
Nyble Nyble::operator+(const char val)
{
return Nyble(getData()+val);
}
Nyble Nyble::operator-(const char value)
{
return Nyble(value + getData()) ;
}``
I am getting an error saying no suitable constructor exists to convert int to Nyble. If so, what constructor should I declare? Else what changes should I make to the overloading function?
You need to add a constructor for Nyble(getData() + val); and Nyble(value + getData()) to work:
class Nyble {
public:
explicit Nyble(char d); // add this
// ...
};
Nyble::Nyble(char d) : data(d) {} // and the implementation
Though, I recommend that you instead implement operator+ and operator- as free functions and make operator+= and operator-= member functions.
It could look like this:
class Nyble {
public:
Nyble() = default;
explicit Nyble(unsigned char d);
// implement operator+= and operator-= as member functions
Nyble& operator+=(const Nyble& n1);
Nyble& operator-=(const Nyble& n1);
unsigned char getData() const;
unsigned char& getData();
private:
unsigned char data = 0;
};
// operator+ and operator- as free functions:
Nyble operator+(Nyble lhs, const Nyble& rhs);
Nyble operator-(Nyble lhs, const Nyble& rhs);
Nyble::Nyble(unsigned char d) : data(d) {}
// the implementation of the member operator overloads:
Nyble& Nyble::operator+=(const Nyble& rhs) {
data += rhs.data;
return *this;
}
Nyble& Nyble::operator-=(const Nyble& rhs) {
data -= rhs.data;
return *this;
}
unsigned char Nyble::getData() const { return data; }
unsigned char& Nyble::getData() { return data; }
// now the free functions can use the member functions
// `operator+=` and `operator-=`:
Nyble operator+(Nyble lhs, const Nyble& rhs) {
return lhs += rhs;
}
Nyble operator-(Nyble lhs, const Nyble& rhs) {
return lhs += rhs;
}

I can't get enum class operators to work

I get an error as
FastOut<NMAX>::Flags FastOut<NMAX>::operator&(FastOut<NMAX>::Flags, FastOut<NMAX>::Flags) must take either zero or one argument
template<int NMAX>
class FastOut{
enum class Flags;
protected:
char buffer[NMAX];
std::map<Flags,bool>FM={(UP,0),(LOW,0),(BOOL,0)};
public:
enum class Flags{upper,lower,boolapha };
friend Flags operator&(Flags a,Flags b);
FastOut();
FastOut(const char *);
FastOut(const std::string&);
FastOut & operator << (int);
FastOut & operator << (char);
FastOut & operator << (long long);
FastOut & operator << (float);
FastOut & operator << (double);
FastOut & operator << (char *);
FastOut & operator << (const std::string &);
FastOut & operator << (const FastOut&);
void open(const char*);
void open(const std::string&);
void flush();
void clear();
~FastOut();
};
template<int NMAX>
typename FastOut<NMAX>::Flags FastOut<NMAX>::operator&(Flags a,Flags b){
}
I want to be able to say FasOut<N>::Flags a= FastOut<N>::Flags::upper | FastOut<N>::Flags::lower
A binary operator member should only take one parameter, the right-hand argument – the left-hand argument is *this.
template<int NMAX>
typename FastOut<NMAX>::Flags FastOut<NMAX>::operator&(Flags rhs) const
{
// Return *this & rhs
}

class method signature with *const* or without *const*?

I get the following error in Eclipse when trying to compile (c++)
../CardDeck.cpp:17:22: error: passing ‘const CardDeck’ as ‘this’ argument of ‘int CardDeck::size()’ discards qualifiers [-fpermissive]
if I change int size() method to int size() const the error msg is gone and its compiled. I dont know why ?
the .H file is the following :
#include "Card.h"
#include <vector>
using namespace std;
class CardDeck{
private:
vector<Card*> deck;
public:
int size();
CardDeck();
CardDeck(const CardDeck& rhs);
CardDeck& operator=(const CardDeck& rhs);
Card& draw();
Card& top();
bool isEmpty();
void clear();
int value();
CardDeck& operator+=(const CardDeck& rhs); /// not sure if to return ref
CardDeck& operator+(const CardDeck& rhs);
friend CardDeck& operator*(unsigned int num,CardDeck& rhs);
friend CardDeck& operator*(CardDeck& lhs,unsigned int num);
bool operator<=(const CardDeck& rhs );
bool operator>=(const CardDeck& rhs);
bool operator<(const CardDeck& rhs);
bool operator>(const CardDeck& rhs);
bool operator==(const CardDeck& rhs);
bool operator!=(const CardDeck& rhs);
Card* operator[](int i);
};
and the C++ file is :
#include "CardDeck.h"
int CardDeck::size() {
return this->deck.size();
}
CardDeck::CardDeck(){};
CardDeck::CardDeck(const CardDeck& rhs){
this->clear();
int i;
for (i=0;i<rhs.size();i++){
Card* current_card = rhs.deck[i];
Card* new_copy = new Card(*current_card);
this->deck.push_back(new_copy);
}
}
Card* CardDeck::operator[](int i) {
return this->deck[i];
}
void CardDeck::clear(){
vector<Card*>::iterator it ;
for(it=this->deck.begin();it != this->deck.end();++it){
Card* temp = *it;
this->deck.erase(it);
delete(temp);
}
}
In your copy constructor CardDeck::CardDeck(const CardDeck& rhs), rhs is a reference to a const CardDeck object.
So rhs.size() will not compile unless size() is explicitly marked as being const. That's what your compiler is telling you.
It's good practice to have your code as const-correct as possible as this prevents errant changes to the member data in a class. Really, isEmpty(), and possibly value() should be marked const too, as should all the overloaded relational operators.

Unhandled exception operator overloading

I am practicing with operator overloading and have built a simple calculator.
template <class one> class calc {
int a;
public:
calc() : a(0) {};
calc(const calc& other) : a(other.a) {}
void print() { cout << a; }
calc& operator += (const calc& other);
calc& operator += (const one& i);
calc& operator -= (const calc& other);
calc& operator -= (const one& i);
calc& operator *= (const calc& other);
calc& operator *= (const one& i);
calc& operator /= (const calc& other);
calc& operator /= (const one& i);
const calc& operator - () const;
friend const calc operator + (const calc& our, const calc& other);
friend const calc operator + (const one& i, const calc& other);
friend const calc operator + (const calc& our, const one& i);
};
But unfortunately, when I try to implement the class, it throws the exception:
Unhandled exception at 0x010154C9 in Proctical programming c++
overloading 1.exe: 0xC00000FD: Stack overflow (parameters: 0x00000001,
0x00192F64).
Here is the main:
int main() {
calc <int> one;
one += 2;
one.print();
cin.get();
}
And the problem occurs, for example, here but consequently also in other operators:
template <class one>
calc<one>& calc <one> :: operator += (const one& i) {
*this += i;
return *this;
}
Could you, please, hint me at what I am doing wrong?
Your function calls itself recursively with no condition to exit:
template <class one>
calc<one>& calc <one> :: operator += (const one& i) {
*this += i;
// ^calls the function youre currently in.
return *this;
}
You need to adjust your += operator to use the + operator that you've defined, or as #PaulMcKenzie stated, do the actual addition in += and have + use +=. For example,
template <class one>
calc<one>& calc <one> :: operator += (const one& i) {
a += i;
return *this;
}
seems to work.
You can see a warning about this if your warning level is high enough:
Warning 1 warning C4717: 'calc::operator+=' : recursive on all control paths, function will cause runtime stack overflow
That being said, there are some other problems with your code, like int a should be one a and
friend const calc operator + (const calc& our, const calc& other);
should just be a normal + operator instead of a friend.

should friend functions be represented in UML diagrams?

Also, how exactly are overloaded operator member functions best formatted in a UML diagram?
Here is my class:
class matrix
{
friend ostream& operator << (ostream&, const matrix&);
friend bool operator == (const matrix &, const matrix &);
friend matrix operator - (const matrix &, const matrix &);
private:
int size;
int range;
int array[10][10];
public:
matrix(int);
matrix(int, int);
bool operator != (const matrix &) const;
matrix operator + (const matrix &) const;
const matrix & operator = (const matrix &);
};
and here is what I have of my UML diagram so far:
By placing the stereotype <<friend>> in front of the operation in the UML class diagram.
You will have to do it this way:
<<friend>> ostream& operator << (ostream&, const matrix&)
<<friend>> bool operator == (const matrix &, const matrix &)
<<friend>> matrix operator - (const matrix &, const matrix &)