Yes I know it sounds weird, but I'm looking for a way to overwrite the indirection operator to return another class object. Let me explain better:
In main.cpp I got
MyInt *V = new MyInt[10];
(*V)[3]=10;
but I would like to have it like:
MyInt *V = new MyInt[10];
V[3]=10;
In MyInt.h I've used a wrapper to catch and remove the square brackets of MyInt class and then overload the "=" operator. That's because I need a class that could store the vector and also a counter of its usage inside it. More details here.
MyInt.h
wrapper operator[] ( std::size_t i ) { return wrapper( *this, i ) ; }
The work flow is "MyInt::wrapper::operator=". Now it works but I would like to get rid of (*V). Would be possible to remove it by overloading the indirection operator to return a wrapper object that could be passed to "wrapper::operator=" then? I was thinking something like:
MyInt& operator*(){
return wrapper(*this)
}
but it doesn't work, I get "error: invalid initialization of non-const reference of type ‘MyInt&’ from an rvalue of type ‘test::wrapper’"
. I know that the indirection operator should return the same class, but I really need it that way. Any suggestion? Thanks in advance.
CodePudding user response:
Note: This answer was written when OPs question was:
I would like to have it like:
MyInt V = new MyInt[10]; V[3]=10;
I'll leave this answer up in case anyone is interested in a solution for that.
#include <cstddef>
class MyInt {
public:
MyInt() = default;
MyInt(MyInt* d) : data(d) {} // constructor taking a `MyInt*`
// ... rule of 5 implementation needed here ...
MyInt& operator[](size_t idx) { return data[idx]; }
MyInt& operator=(int) { return *this; }
private:
MyInt* data = nullptr;
};
int main() {
MyInt V = new MyInt[10];
V[3]=10;
}
Note that there's no way for V
to know how many elements data
is pointing at.
CodePudding user response:
Following the link to your earlier question, and the requirements you've added there, V[3]
is undefined behaviour.
You have changed the meaning of new []
to return a pointer to a single object.
You need to completely rethink your design, such that there are 10 MyInt
objects for V
to point to.
struct MyCounts
{
int num_read = 0;
int num_write = 0;
};
class MyInt
{
int value;
MyCounts * counts;
static void* operator new[](size_t n){
void * ptr = malloc(sizeof(MyCounts) n * sizeof(MyInt));
MyCounts * counts = new (ptr) MyCounts;
ptr = static_cast<void *>(counts 1);
for (size_t i = 0; i < n; i, ptr = sizeof(MyInt)) {
new (ptr) MyInt{ counts };
}
return static_cast<void *>(counts 1);
}
static void* operator delete[](void* ptr, size_t n){
for (MyInt * last = reinterpret_cast<MyInt *>(ptr) n; --last != ptr; ) {
last->~MyInt();
}
ptr -= sizeof(MyCounts);
reinterpret_cast<MyCounts *>(ptr)->~MyCounts();
free(ptr);
}
public:
MyInt& operator=(int i) { value = i; counts->num_write; return *this; }
operator int() const { counts->num_read; return value; }
};
CodePudding user response:
I would like to have it like:
MyInt* V = new MyInt[10]; V[3]=10;
You need MyInt
to implement an operator=
taking an int to "write" to it, and a conversion oeprator to "read" from it:
#include <iostream>
struct MyInt
{
int value;
MyInt& operator=(int v) { value = v; return *this; }
operator int() const { return value; };
};
int main()
{
MyInt *V = new MyInt[10];
V[3]=10;
std::cout << V[3] << '\n';
}