Pertanyaan Destructor dipanggil pada objek yang tidak diinginkan selama tugas


myClassVar = MyClass(3);  

Saya berharap destructor dipanggil pada yang dibuat sebelumnya myClassVar di kiri.
Tetapi sebenarnya dipanggil pada objek baru yang dibuat oleh MyClass(3).

Kode dan output uji lengkap saya mengikuti ..

sunting

Bagaimana cara saya memperbaiki masalah?
Menerapkan operator penugasan?
MyClass sebenarnya memiliki pointer, dan MYSQL_STMT *, saya bertanya-tanya bagaimana saya harus berurusan dengan variabel MYSQL_STMT *.

Saya hanya perlu MyClassVar (3) objek bukan MyClassVar () yang pertama kali dibuat ketika objek ClientClass dibuat.

Saya menemukan situasi ini cukup sering, dan bertanya-tanya apakah ada cara yang baik untuk melakukannya.

#include <stdio.h>

class MyClass
{
public:
    MyClass() { printf("MyClass %p\n", this); }
    MyClass(int a) { printf("Myclass(int) %p\n", this); }
    ~MyClass() { printf("~MyClass %p\n", this); }

private:
    int mA;
};


class ClientClass
{
public:
    void Foo()
    {
        printf("before &myClassVar : %p\n", &myClassVar);
        myClassVar = MyClass(3); // this is the important line
        printf("after &myClassVar : %p\n", &myClassVar);
    }

private:
    MyClass myClassVar;
};

int main()
{   
    ClientClass c;
    c.Foo();
    return 0;
}

MyClass 0x7fff5fbfeba0
before &myClassVar : 0x7fff5fbfeba0
Myclass(int) 0x7fff5fbfeb70
~MyClass 0x7fff5fbfeb70 // <--- here destructor is called on the newly created object
after &myClassVar : 0x7fff5fbfeba0
~MyClass 0x7fff5fbfeba0

5
2017-10-28 06:51


asal


Jawaban:


Beginilah cara garis kritis terputus:

myClassVar = MyClass(3);

Pertama, MyClass(3) memanggil konstruktor dan mengembalikan objek.

Kedua, myClassVar = menyalin objek ke myClassVar.

Maka pernyataan itu berakhir. Objek (yang merupakan segera) mati, dan dengan demikian destructor dipanggil.

EDIT:

Adapun cara mengatasi ini. Satu-satunya cara saya bisa memikirkan adalah menggunakan penempatan baru. Saya tidak yakin apakah ada solusi yang lebih baik selain membuat metode "set".


6
2017-10-28 06:55



myClassVar = MyClass(3);

myClassVar terus ada setelah baris ini. Seumur hidup MyClass(3) berakhir pada titik koma.


2
2017-10-28 06:55



Seperti posting lain disebutkan objek dengan konstruktor kustom MyClass(3) dihancurkan setelah operasi penugasan myClassVar = MyClass(3). Dalam hal ini Anda tidak perlu operator penugasan khusus karena compiler yang dihasilkan satu salinan anggota mA ke objek yang sudah ada myClassVar.

Namun karena MyClass mendefinisikan destructor sendiri, Anda harus mematuhi aturan tiga, yang mengamanatkan bahwa dalam kasus seperti itu Anda harus menerapkan operator penugasan kustom juga.


2
2017-10-28 07:14



Menanggapi hasil edit Anda: bagaimana Anda memperbaiki masalah apa? Itu tidak jelas apa masalahnya. Jika kelas Anda membutuhkan perusak (dan tidak ada polimorfisme dalam bermain), itu mungkin membutuhkan kedua operator penugasan dan sebuah konstruktor copy. Demikian pula, ketika "pelacakan" konstruksi dan penghancuran, Anda mungkin harus menyediakan keduanya juga, karena mereka akan melakukannya disebut.

Jika tidak: jika masalahnya adalah Anda sedang membangun dan kemudian menugaskan, daripada membangun dengan nilai yang benar dengan segera, Jawaban sederhananya adalah "jangan lakukan itu". Compiler melakukan apa yang Anda katakan untuk. Jika Anda menulis:

MyClass var;
var = MyClass(3);

Anda memiliki konstruksi standar, diikuti oleh pembangunan a sementara, tugas, dan penghancuran sementara. Jika kamu menulis:

MyClass var(3);

atau

MyClass var = 3;

Anda hanya memiliki satu konstruksi. (Perhatikan bahwa meskipun ada penampilan, di sana aku s tidak tugas di potongan terakhir. Hanya konstruksi.)

Untuk anggota kelas, perbedaan ini muncul dalam cara Anda menulis konstruktor:

ClientClass::ClientClass() { var = MyClass(3); }

adalah konstruksi default, diikuti oleh pembuatan, tugas, dan penghancuran sementara;

ClientClass::ClientClass() : var( 3 ) {}

hanya konstruksi dengan nilai yang benar. (Agak jelas, ini bentuk kedua lebih disukai.)


1
2017-10-28 08:01