私の意見では、C ++の危険性はいくぶん誇張されています。
本質的な危険はこれです。C#ではunsafe
キーワードを使用して「安全でない」ポインター操作を実行できますが、C ++(ほとんどがCのスーパーセットである)を使用すると、いつでもポインターを使用できます。メモリーリーク、バッファーオーバーフロー、ぶら下がりポインターなど、ポインターの使用に固有の通常の危険性(Cと同じ)に加えて、C ++は、物事を真剣に台無しにする新しい方法を導入します。
Joel Spolskyが言っていたこの「余分なロープ」は、基本的に1つのことです。「Rule of 3」としても知られる独自の記憶を内部で管理するクラスを書くことですC ++ 11のof of 4またはRule of 5)。つまり、内部で独自のメモリ割り当てを管理するクラスを作成したい場合は、何をしているのかを知る必要があります。そうしないと、プログラムがクラッシュする可能性があります。コンストラクター、コピーコンストラクター、デストラクター、および代入演算子を慎重に作成する必要がありますが、これは驚くほど簡単に間違えやすく、多くの場合、実行時に奇妙なクラッシュを引き起こします。
しかし、実際の毎日のC ++プログラミングでは、独自のメモリを管理するクラスを作成することは非常にまれです。したがって、C ++プログラマはこれらの落とし穴を回避するために常に「注意」する必要があると誤解されます。通常、次のようなことを行うだけです。
class Foo
{
public:
Foo(const std::string& s)
: m_first_name(s)
{ }
private:
std::string m_first_name;
};
このクラスは、JavaまたはC#で行うことと非常によく似ています-明示的なメモリ管理を必要とせず(ライブラリクラスstd::string
がすべてを自動的に処理するため)、「Rule of 3」はデフォルトからまったく必要ありませんコピーコンストラクタと代入演算子は問題ありません。
次のようなことをしようとするときだけです:
class Foo
{
public:
Foo(const char* s)
{
std::size_t len = std::strlen(s);
m_name = new char[len + 1];
std::strcpy(m_name, s);
}
Foo(const Foo& f); // must implement proper copy constructor
Foo& operator = (const Foo& f); // must implement proper assignment operator
~Foo(); // must free resource in destructor
private:
char* m_name;
};
この場合、初心者が割り当て、デストラクタ、およびコピーコンストラクタを正しく取得するのは難しい場合があります。しかし、ほとんどの場合、これを行う理由はありません。C ++では、std::string
やなどのライブラリクラスを使用することで、99%の時間で手動メモリ管理を簡単に回避できますstd::vector
。
別の関連する問題は、例外がスローされる可能性を考慮しない方法でメモリを手動で管理することです。お気に入り:
char* s = new char[100];
some_function_which_may_throw();
/* ... */
delete[] s;
some_function_which_may_throw()
実際に例外がスローされた場合、割り当てられたメモリs
は再利用されないため、メモリリークが発生します。しかし、繰り返しますが、実際には、これは「Rule of 3」が実際にはもうあまり問題ではないのと同じ理由でほとんど問題ではありません。生のポインタを使用して実際に独自のメモリを管理することは非常にまれです(通常は不要です)。上記の問題を回避するには、std::string
またはを使用するだけでstd::vector
、例外がスローされた後のスタックの巻き戻し中にデストラクタが自動的に呼び出されます。
そのため、ここでの一般的なテーマは、自動初期化/破棄、コピーコンストラクター、例外など、Cから継承されなかった C ++機能の多くが、C ++で手動メモリ管理を行う際にプログラマーに特に注意を払うことです。ただし、これは、最初に手動のメモリ管理を行う場合にのみ問題になります。これは、標準のコンテナとスマートポインタを使用している場合にはもうほとんど必要ありません。
だから、私の意見では、C ++は余分なロープをたくさん与えてくれますが、それを使ってぶらぶらする必要はほとんどありません。ジョエルが話していた落とし穴は、現代のC ++で簡単に避けることができます。
Your questions should be reasonably scoped. If you can imagine an entire book that answers your question, you’re asking too much.
。これはそのような質問として適格だと思います