参照が必要な理由?

C++習得中。デストラクタの振る舞いが納得いかん。

#include <cstdio>

class Person {
    char *myname;
  public:
    Person(char *name) {
        this->myname = name;
        printf("%s: constructor\n", this->myname);
    }

    ~Person() {
        printf("%s: destructor\n", this->myname);
    }
};


int main() {
    Person p1("John"), p2("Tom");

    p1 = p2;
    return 0;
}

/* 標準出力
John: constructor
Tom: constructor
Tom: destructor
Tom: destructor
*/

classが構造体の拡張だってことを考えれば、これはまだ直感的に分かる。

しかしこれはどうだ、

#include <cstdio>

class Person {
    char *myname;
  public:
    Person(char *name) {
        this->myname = name;
        printf("%s: constructor\n", this->myname);
    }

    ~Person() {
        printf("%s: destructor\n", this->myname);
    }
};


void noop(Person p) {
    // 何もしない
}


int main() {
    Person p("John");
    noop(p);
    return 0;
}

/* 標準出力
John: constructor
John: destructor
John: destructor
*/

仮引数の分までデストラクタ呼んでるやん。そりゃコピーだけどさ。

注意しないとデストラクタが2回呼ばれるとか、他の言語じゃありえない。