0

Imagine, I have some class :

class MyClass{
    public:
        MyClass(unsigned int N): a(new double[N]){};
        ~MyClass(){delete[] a;};

    private:
         double* a;
}

In another class, i use a pointer to this class :

class MyOtherClass{
    public:
        MyOtherClass(unsigned int N):p(new MyClass(N)){};
        ~MyOtherClass(){delete p;};

        MyClass* get_MyClass(){return p;};

    private:
        MyClass *p;
}

Then, in the main I need to get MyClass which is contained in MyOtherClass

int main(){
    MyOtherClass moc(1e100);
    MyClass mc;

    mc <-> moc.get_MyClass();
}

the <-> is where I'm stuck. I want that mc becomes what p points to but without copying the (huge) static array. Is there a way to do this conversion efficiently ?

Edit

thanks for your answers but i will precise something. as the time consuming part of the copy of MyClass comes from the copy of the static array, i thought i could do something like :

class MyClass{
    public:
        MyClass(unsigned int N): a(new double[N]),del(true){};
        MyClass(MyClass* mc): a(mc.get_a()),del(true){};
        ~MyClass(){if(del){delete[] a;}};

        double* get_a(){
            del = false;
            return a;
        }

    private:
         double* a;
         bool del;
}

with the main :

int main(){
    MyOtherClass moc(1e100);
    MyClass mc(moc.get_MyClass());
}

but i don't know if i will have memory leaks...

PinkFloyd
  • 2,103
  • 4
  • 28
  • 47

4 Answers4

3

Use reference:

int main(){
    MyOtherClass moc(1e100);
    MyClass& mc = *moc.get_MyClass();
}

With reference you can avoid the copying and still avoid using pointer syntax.

Periodic Maintenance
  • 1,698
  • 4
  • 20
  • 32
1

Assuming you want p contents destroyed, write a move constructor for MyClass.

In general, storing raw pointers like you do is problematic in general. If you used vector<double> instead, the whole task would be much easier, because in this approach unnecessary use of pointers is only adding you problems.

That's how I'd do that:

class MyClass{
    std::vector<double> a;
public:
    MyClass(unsigned int N): a(N) { }
    // no destructor!
};

class MyOtherClass{
    MyClass p;
public:
    MyOtherClass(unsigned int N) : p(N) {};
    // no destructor!!

    MyClass& getMyClass() { return p; };
}

Now it can be clearly seen you can't just use getMyClass to initialize new MyClass without copying, because it's a reference. However, if you are sure you won't need to use MyOtherClass later, or perhaps you just want to "steal" its data, you should be able to safely move it out the MyOtherClass:

MyClass(MyClass&& other) : a(std::move(other.a)) {
    // now, I am not sure what will be left in other.a, but you can clean it up
    // (you can because it's in valid, only undefined state)
    other.a = std::vector<double>();
}

If you are not interested in stealing the data, but want to just access it, use, as others suggested, a reference.

Bartek Banachewicz
  • 38,596
  • 7
  • 91
  • 135
  • thanks but i have to use static arrays... the code i use has been developed by someone else and i can't afford the rewriting of everything... but yeah, what i want is to "steal" datas... – PinkFloyd Jun 26 '13 at 14:30
0

You should change the return type of

MyClass* get_MyClass(){return p;};

to

MyClass& get_MyClass(){return p;};

because what you described seems to be the main usage of this function.

Then just retrieve the instance with :

MyClass& mc = moc.get_MyClass ();
Jerska
  • 11,722
  • 4
  • 35
  • 54
0

According to your code, double* MyClass::a; array could not be copied because of default copy constructor/copy operator performs just reassign of a pointers;

You should use smart pointer to wrap your double* MyClass::a variable to enable reference count and prevent execute delete operator twice on same addr inside of destructor.

You should navigate to this article and read about.

How to use smart pointer with array you can found here

Community
  • 1
  • 1