0

I'm designing a class that's wrapper of a 2D array. Anything seems ok, except the destruction function. I don't know why it throws an access violent reading.

I have tried to detect what happened and I still can't solve this problem. I need your help. Thank you.

class ClassA
{
    int Num;
public:
    ClassA()
    {}
    ~ClassA(void)
    {}
};


class ClassB
{
        ClassA* pA;
public:
    ClassB()
    {}
    ClassB(ClassA obj)
    {
        pA = new ClassA[1];
        pA[0] = obj;
    }
    ~ClassB(void)
    {
        delete[] pA;
    }

    ClassB::ClassB(ClassB& src)
    {
        this->~ClassB();

        pA = new ClassA[1];
        pA[0] = src.pA[0];
    }


    ClassB& ClassB::operator =(const ClassB& src)
    {
        if (this == &src)
            return *this;

        this->~ClassB();

        pA = new ClassA[1];
        pA[0] = src.pA[0];

        return (*this);
    }
};

ClassB Test5()
{
    ClassA A;


    ClassB B( A );

    return B;
}

void Test6()
{   
    ClassB B;
    B = Test5();
}

The exception will be thrown after finishing of Test6 function.

dnvThai
  • 123
  • 8

1 Answers1

0

Get out of the habit of explicitly calling destructors. Such an act does not reinitialise the object or its (non-static) members - it logically destroys the object so it cannot be used.

this->~ClassB() makes any attempt to access non-static members of the current object (i.e. *this) give undefined behaviour.

For example, in the copy constructor of ClassB

ClassB::ClassB(ClassB& src)
{
    this->~ClassB();

    pA = new ClassA[1];
    pA[0] = src.pA[0];
}

the accesses of pA in the last two statements are (implicitly) this->pA. So they both have undefined behaviour.

There are circumstances where explicitly calling a destructor is appropriate. But assignment operators and copy constructors are generally not among those circumstances.

Peter
  • 35,646
  • 4
  • 32
  • 74