effective c+(05)(06)のc++が黙々と作成して呼び出す関数
5791 ワード
1.空のクラスが1つしか書かれていない場合、コンパイラはcopyコンストラクション関数、copy assignment関数、およびコンストラクション関数を宣言します.次のようになります.
次のように書きます.
コンパイラでは、次のコードが実装されます.
コンパイラはnon-virtual関数を生成します.デフォルトでは、以上の4つのコンストラクション関数が生成されます.
これらのコンパイラがデフォルトで生成した関数を無効にするには、次の2つの方法があります.
一.これらの関数をprivateとして宣言します.次のようになります.
次のように呼び出されます.
コンパイラでは許可されません.しかし,この場合はmember関数やfriend関数内で行えばよい.
二.すべてのメンバーおよびクラスがオブジェクトをコピーできないことを保証するには、次のクラスを定義する必要があります.
そして
これにより、コンパイラは、メンバー関数またはfriend関数のいずれかがEmptyオブジェクトをコピーしようとすると、copyコンストラクション関数とcopy assignmentオペレータを生成しようとしますが、base class対応の兄弟を呼び出そうとすると、操作を拒否します.
2.
コンパイラはすでにNamedObjectクラスにcopyコンストラクタを定義しているので、NamedObjectno 2(no 1)はこのcopyコンストラクタを呼び出します.
3.
c++は、referenceが異なるオブジェクトを指すことを許可しません.「reference」メンバーを含むclass内で付与操作をサポートする場合は、copy assignmentオペレータを定義する必要があります.同様にconstを含むメンバーのクラスについてもconstを変更するのは合法ではありません.
4.base classがcopy assignmentをprivateとして宣言した場合、コンパイラはderived classesのcopy assignmentオペレータの生成を拒否します.コンパイラがderived classesのために生成したcopy assignmentオペレータはbase class成分を処理できるからです.
まとめ:コンパイラはclassのdefaultコンストラクション関数、copyコンストラクション関数、copy assignmentオペレータ、およびコンストラクション関数を暗黙的に作成できます.
転載先:https://www.cnblogs.com/2011winseu/p/3184909.html
次のように書きます.
class Empty{ };
コンパイラでは、次のコードが実装されます.
class Empty{
Empty(){} //
Empty(const Empty& rhs ) {} //
~Empty() {} //
Empty& operator=( const Empty& rhs ) {} //
};
コンパイラはnon-virtual関数を生成します.デフォルトでは、以上の4つのコンストラクション関数が生成されます.
これらのコンパイラがデフォルトで生成した関数を無効にするには、次の2つの方法があります.
一.これらの関数をprivateとして宣言します.次のようになります.
class Empty{
public:
private:
Empty(const Empty& rhs ) {}
};
次のように呼び出されます.
Empty e1;
Empty e2(e1);
return 0;
コンパイラでは許可されません.しかし,この場合はmember関数やfriend関数内で行えばよい.
二.すべてのメンバーおよびクラスがオブジェクトをコピーできないことを保証するには、次のクラスを定義する必要があります.
class Uncopyable{
protected:
Uncopyable() {}
~Uncopyable(){}
private:
Uncopyable( const Uncopyable& );
Uncopyable& operator=( const Uncopyable& );
};
そして
class Empty:private Uncopyable{
.......
};
これにより、コンパイラは、メンバー関数またはfriend関数のいずれかがEmptyオブジェクトをコピーしようとすると、copyコンストラクション関数とcopy assignmentオペレータを生成しようとしますが、base class対応の兄弟を呼び出そうとすると、操作を拒否します.
2.
class NamedObject{
public:
NamedObject( const char* name, const T& value );
NamedObject( const string& name, const T& value );
private:
string nameValue;
T objectValue;
};
NamedObject<int> no1( "Smallest Prim Number", 2 );
NamedObject<int> no2(no1);
コンパイラはすでにNamedObjectクラスにcopyコンストラクタを定義しているので、NamedObject
3.
template< typename T >
class NamedObject{
public:
NamedObject( const string& name, const T& value );
private:
string& nameValue;
const T objectValue;
};
string newDog("persephone");
string oldDog("Satch");
NamedObject<int> p( newDog, 2 );
NamedObject<int> s( oldDog, 36 );
p = s;
c++は、referenceが異なるオブジェクトを指すことを許可しません.「reference」メンバーを含むclass内で付与操作をサポートする場合は、copy assignmentオペレータを定義する必要があります.同様にconstを含むメンバーのクラスについてもconstを変更するのは合法ではありません.
4.base classがcopy assignmentをprivateとして宣言した場合、コンパイラはderived classesのcopy assignmentオペレータの生成を拒否します.コンパイラがderived classesのために生成したcopy assignmentオペレータはbase class成分を処理できるからです.
まとめ:コンパイラはclassのdefaultコンストラクション関数、copyコンストラクション関数、copy assignmentオペレータ、およびコンストラクション関数を暗黙的に作成できます.
転載先:https://www.cnblogs.com/2011winseu/p/3184909.html