代入中に不要なオブジェクトに対してデストラクタが呼び出される

myClassVar = MyClass(3);  

左にある、以前に作成された myClassVar に対してデストラクタが呼び出されると思いました。
しかし、実際には MyClass(3)によって作成された新しいオブジェクトで呼び出されています。

私の完全なテストコードと出力は続きます..

編集

問題を解決するにはどうすればよいですか?
代入演算子を実装しますか?
MyClassには実際にポインタがあり、MYSQL_STMT *はMYSQL_STMT *変数をどのように扱うべきなのでしょうか?

私は、ClientClassオブジェクトの作成時に最初に作成されたMyClassVar()ではなく、MyClassVar(3)オブジェクトが必要です。

私はかなり頻繁にこの状況に遭遇し、それを行う良い方法があるのだろうかと思っています。

#include 

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
私はあなたの編集に対処するために私の答えを編集しました。
追加された 著者 Mysticial,

4 答え

クリティカルラインがどのように壊れているかは次のとおりです。

myClassVar = MyClass(3);

最初に、 MyClass(3)はコンストラクタを呼び出し、オブジェクトを返します。

次に、 myClassVar = はオブジェクトを myClassVar にコピーします。

次に、ステートメントが終了します。オブジェクト(即時です)は死んでいるので、デストラクタが呼び出されます。

編集:

これを回避する方法については。私が考えることができる唯一の方法は、プレースメント新しいを使用することです。私は、 "set"メソッドを作る以外のよりよい解決策があるかどうかはわかりません。

6
追加された
"set"メソッドでは、コピーコンストラクタと代入演算子を意味しますか?
追加された 著者 eugene,
より効率的な方法で2つを組み合わせた別の方法にもっと似ています。基本的には、既存のオブジェクトを破棄して新しいオブジェクトを作成します。 (これはクラス内で定義する必要があります)
追加された 著者 Mysticial,
myClassVar = MyClass(3);

myClassVar continues to exist after this line. The lifetime of MyClass(3) ends at the semicolon.

2
追加された

他の投稿と同様に、カスタムコンストラクタ MyClass(3)を持つオブジェクトは、割り当て操作 myClassVar = MyClass(3)の後で破棄されます。この場合、カスタム代入演算子は必要ありません。これは、コンパイラーがメンバーmyClassVarに mA というメンバーをコピーしたためです。

しかし、MyClassは独自のデストラクタを定義しているので、 3つのルールのように、カスタム代入演算子も実装する必要があります。

2
追加された

あなたの編集への応答:どのように問題を解決しますか?それははっきりしていません 何が問題なの?あなたのクラスがデストラクタを必要とする場合(そして 遊びの多型性)、おそらく代入演算子と コピーコンストラクタ同様に、建築物を「追跡する」と あなたはおそらく両方を提供するべきでしょう。 呼び出される。

それ以外の場合:問題があなたが構築している場合、 すぐに正しい値で構築するのではなく、 簡単な答えは「しないでください」です。コンパイラはあなたがそれを伝えます に。あなたが書く場合:

MyClass var;
var = MyClass(3);

あなたはデフォルトの構造を持っています。 一時的な、割り当て、および一時的なの破壊。もし、あんたが 書きます:

MyClass var(3);

または

MyClass var = 3;

あなたは1つの構造しか持っていません。 (外観にもかかわらず、そこに 最後のスニペットでいいえの割り当てです。唯一の建設。)

Fまたは class members, this difference appears in the way you write the constructまたは:

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

is default construction, followed by creation, assignment and destruction of a tempまたはary;

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

is just construction with the cまたはrect value. (Rather obviously, this second fまたはm is preferred.)

1
追加された