2013-05-26 6 views
14

たとえば、クラスを宣言したいが、クライアントがコピーコンストラクタ(またはコピー代入演算子)を使用できないようにしたいコンストラクタをprivateと= deleteの間で宣言するのはどちらですか?

次の2つのどちらもコピーコンストラクタを使用できません。

class Track 
{ 
public: 
    Track(){}; 
    ~Track(){}; 
private: 
    Track(const Track&){}; 
}; 

class Track 
{ 
public: 
    Track(){}; 
    ~Track(){}; 
    Track(const Track&)=delete; 
}; 

これらの方法のうちの1つは、他のものよりも「正しい」か、それとも同等であるか?副作用はありますか?それは単に削除しながら

//Does not compile with both the above ways 
int main() 
{ 
    Track l; 
    Track p(l); 
} 
+0

これは 'Track(const Track&)= delete;をコンパイルしますか? ' –

+1

@EdHealはい、そうです。 g ++ 4.7 –

+0

以前にこのような 'delete'の使用は見られませんでした。言語拡張?もしそうであれば、最初のものが間違いなくもっと正確である – kotlomoy

答えて

15

プライベートにすることは、「古い」方法です。コンストラクタはまだ存在しますが、プライベートなので、別のクラスメンバ関数内からのみ呼び出すことができます。

= deleteコンストラクタを削除します。コンパイラによって生成されるものではなく、単純に存在しません。

ほとんどの場合、= deleteはあなたが望むものです。 (ただし、すべてのコンパイラがこの構文をまだサポートしていないので、移植性が懸念される場合は...)

6

privateは依然としてTrackクラスのメンバー関数は、そのクラスのインスタンスをコピー構築することを可能にするコピーコンストラクタを宣言すると、そのオブジェクトのコピーが、構築禁止します。 C++ 11では

、あなたがメンバーTrackの機能、またはの友人を聞かせすることは理にかなって当然のない限り、コピーコンストラクタを削除すると、クラスが非コピー可能であるという事実を(表現する正しい方法ですTrack、コピー構成体Trackオブジェクト)。

5

コンストラクタをプライベートにすることは、基本的に古いC++の「ハック」でした。ユーザーが使用できないようにします。 deleteの特別なメンバ関数はC++ 11でしか導入されておらず、クラスをコピーすることができないと言ってもよいでしょう。 という意図が明示されているので、です。

プライベートコンストラクタは、その使用を完全に禁止する以外にも使用できます(静的なクラスメンバ関数によって呼び出すなど)。だから、コンストラクタをプライベートにするだけでは、意図をうまく伝えられず、その結果生じるエラーもあまり明確ではありません。

0

あなたの最初のアプローチは、クラス自体が自分自身をコピーすることを妨げません。これを解決する伝統的な方法は、コピーコンストラクタprivate を実装しないように宣言することです。

しかし、その問題は、意図が明白でないことがあります。誰かがコードを読んでいると、なぜ孤立宣言が存在し、間違ってそれを削除するのか理解できないかもしれません。 Boostが利用可能な場合は、boost::noncopyableから個人的に継承されるようにコメントが役に立ちます。

第2のアプローチでは、意図が明確になり、C++ 11を使用できる場合にはどのような方法を選ぶべきですか。

0

最初の解決策は、コピーコンストラクタがプライベートであり、使用されないことを読者に伝えます。 2番目のソリューションはC++ 11でのみ有効です。このため、プライベートプロパティを使用して、移植性と読み易い実装が最初の実装になると思います。

0

C++ 11の場合は、deleteを使用してください。その理由は、コールを明示的にして意図を明確にするからです。誤ってプライベートコンストラクタを使用することもありますが(たとえば、制限されたスコープのセット)、コンパイラは削除されたコンストラクタを使用することを禁止します。これは、アクセスエラーが発生していない結果が、呼び出し場所に戻って追跡するのは難しいことができリンクエラー、 - プライベートコンストラクタの

1つの問題は、クラスや友人は​​まだそれを使用することができるということです。

あなたに必要なツールチェーンを削除コンストラクタ(= delete)をサポートしていない場合は(あなたの質問に見られるように)、あなたはそれを定義するべきではありません - だけ宣言それは未定義のまま、例えば:でprivate: \n Track(const Track&);

0

基本的にプライベートコピーコンストラクタを宣言してから、実装を提供していません。それらを非公開と宣言することで、非会員はそれをコピーすることができません。

2番目のケースでは、構文はコピーの作成を禁止します。これはC++のネイティブです。

プログラマとしての主な違いは、読みやすさとコードの理解です。最初のケースは冗長で、なぜコピーコンストラクタを宣言し、それをプライベートにし、それを実装しないのですか?クライアントはここで多くのことを推測しなければなりません。

"= delete"を使用して、何をしようとしているのかを明確に示すことができます。

関連する問題