[面接珠玉]C++空クラスのデフォルト関数


面接に参加したとき、面接官はこの質問に答えました.私の答えは、デフォルトコンストラクタ、デフォルトコンストラクタ、デフォルトコピーコンストラクタ、デフォルト付与関数です.今思い出すと気分が悪いので、googleについて、この簡単そうな問題を明らかにします.
空のclassはC++コンパイラで処理された後、空ではありません.コンパイラは自動的にmember functionを宣言します.
class A{};コンパイラが処理すると、次のようになります.
class A
{ 
public: 
A();  //      
A(const A&);  //      
~A();  //    
A& operator=(const A& rhs); 
A* operator&();  //      
const A* operator&() const;
}; 

基本的に私の前の答えに合っていますが、アドレス演算子を取る2つの関数が増えています.
この答えは正しいですか.
実はこのような空のクラスにとって、全く必要ありません.コンパイラもそうではありません.コンパイラのやり方は次のとおりです.
コンパイラは、これらの関数を使用し、表示されていない宣言が必要な場合にのみ、対応する関数を自動的に宣言します.  
例えばA a;コンパイラは上記の例に基づいてクラスAにコンストラクタとコンストラクタを生成する.A b(b)を使用する場合.コンパイラはクラスAのコピーコンストラクタを生成します.    A   c;    c   =   a;コンパイラは付与演算子関数A&d=aを生成する.コンパイラはアドレス演算子関数を生成します.インスタンス化されていない空のクラスでは、コンパイラは関数を生成しません.空のクラスをインスタンス化すると、必要に応じて対応する関数が生成されます.この理論は同様に非空クラス(関数ではなく変数のみを宣言する)に適している.
余談ですが、覚えやすいです.
デフォルトのコピー付与オペレータは、生成されたコードが正当であり、意味があることを証明する機会がある場合にのみ生成されます.これは、「参照メンバーを含む」または「constメンバーを含む」クラスで付与操作をサポートする場合、デフォルトのコピー付与オペレータを定義する必要があることを示します.C++自体は、異なるオブジェクトを参照したり、constメンバーを変更したりすることはできません.最後に、ベースクラスが独自のデフォルトコピー付与オペレータをprivateとして宣言すると、サブクラスは独自のデフォルトコピー付与オペレータを生成しません.このようなデフォルトコピー付与オペレータが生成されると、ベースクラスのデフォルトコピー付与オペレータを呼び出してベースクラスの部分を処理しようとするため、残念ながら権利がありません.コピーコンストラクション関数またはデフォルトのコピー付与オペレータをprivateとして宣言できます.これにより、メンバー関数を明確に宣言すると、コンパイラが暗に作成したデフォルトバージョンがブロックされ、これらの関数はprivateであり、人々が呼び出すのを阻止することができます.クラス自体のmemberとfriendがこれらのprivate関数を呼び出すことができるため、上記の方法には危険があります.「メンバー関数をprivateとして宣言し、故意に実装しない」という難しい方法があります.これにより、デフォルトの関数の生成が阻止され、これらの関数を呼び出してみると、リンクエラーが発生します.宣言のみ、定義なし、リンクが間違っています.宣言するときも、パラメータを書く必要はありません.
クラスにポインタ変数がある限り、自分でコピー構造関数と付与関数を書かなければなりませんが、これらの関数を必要としないと判断した場合、これらの関数をprivate宣言して実現することはできません.これにより、誰かが呼び出すことを防止し、コンパイラが生成することを防止します.
カスタムレプリケーションコンストラクタがない場合、デフォルトのレプリケーションコンストラクタが作成されますが、システムが作成したデフォルトのレプリケーションコンストラクタは「浅いコピー」のみを実行し、コピーされたオブジェクトのデータ・メンバーの値を新しく作成したオブジェクトに割り当てます.このクラスのデータ・メンバーにポインタ・メンバーがある場合、新しいオブジェクトのポインタが指すアドレスがコピーされたオブジェクトのポインタが指すアドレスと同じになり、deleteポインタをdeleteするとdeleteが2回繰り返されてエラーが発生します.