На мою думку, небезпека С ++ дещо перебільшена.
Основна небезпека полягає в наступному: хоча C # дозволяє виконувати "небезпечні" операції вказівника за допомогою unsafeключового слова, C ++ (в основному це набір C) дозволить вам використовувати покажчики, коли вам це заманеться. Окрім звичних небезпек, пов’язаних із використанням покажчиків (які однакові із C), як-от витоку пам'яті, переповнення буфера, вивішування покажчиків тощо, C ++ пропонує вам нові способи серйозно викрутити речі.
Ця "додаткова мотузка", про яку говорив Йоел Спольський , в основному зводиться до одного: написання класів, які внутрішньо управляють власною пам'яттю, також відоме як " Правило 3 " (яке тепер можна назвати Правилом 4 або Правило 5 у З ++ 11). Це означає, що якщо ви хочете коли-небудь написати клас, який керує власними розподілами пам'яті внутрішньо, ви повинні знати, що ви робите, інакше ваша програма, швидше за все, вийде з ладу. Ви повинні ретельно створити конструктор, копіювати конструктор, деструктор та оператор присвоєння, що напрочуд легко помилитися, що часто призводить до химерних збоїв під час виконання.
ЗАРАЗ , у фактичному щоденному програмуванні на C ++, дуже рідко дійсно написати клас, який керує власною пам'яттю, тому оманливо говорити, що програмістам C ++ завжди потрібно бути обережними, щоб уникнути цих підводних каменів. Зазвичай ви просто будете робити щось більше, як:
class Foo
{
public:
Foo(const std::string& s)
: m_first_name(s)
{ }
private:
std::string m_first_name;
};
Цей клас схожий на те, що ви робите в Java або C # - він не вимагає явного керування пам’яттю (оскільки бібліотечний клас std::stringдбає про все, що автоматично), і ніяких матеріалів «Правила 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 ++ дозволяє дуже легко уникнути ручного управління пам’яттю в 99% часу, використовуючи бібліотечні класи типу std::stringі std::vector.
Інша пов’язана проблема - це керування пам’яттю вручну таким чином, що не враховує можливість викидання виключень. Подобається:
char* s = new char[100];
some_function_which_may_throw();
/* ... */
delete[] s;
Якщо на some_function_which_may_throw()самому ділі це згенерує виняток, ви залишаєтеся з витоком пам'яті , тому що пам'ять , виділена для sніколи не буде утилізована. Але знову ж таки, на практиці це навряд чи є проблемою з тієї ж причини, що "Правило 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.. Я вважаю, що це є таким питанням ...