Home > database >  C return another class object
C return another class object

Time:10-15

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';
}
  • Related