C ++ має три способи передачі параметрів функції: за значенням, за посиланням lvalue та за посиланням rvalue. З них передача за значенням створює право власності в тому сенсі, що викликана функція отримує власну копію, а передача посилання на значення rvalue вказує на те, що значення може бути спожито, тобто більше не буде використовуватися абонентом. Проходження посилання на значення lvalue означає, що об'єкт тимчасово запозичений у абонента.
Однак вони, як правило, є "за домовленістю" і не завжди можуть перевіряти компілятор. І ви можете випадково перетворити посилання lvalue в посилання на rvalue, використовуючи std::move()
. Конкретно, є три проблеми:
Посилання може переживати об'єкт, на який він посилається. Система життя Руста запобігає цьому.
У будь-який час може бути більше однієї змінної / неконтрольованої посилання. Перевірка позики Раста запобігає цьому.
Ви не можете відмовитись від посилань. Ви не можете побачити на сайті виклику, чи створює ця функція посилання на ваш об'єкт, не знаючи підпису викличеної функції. Тому ви не можете надійно запобігти посиланням, ні шляхом видалення будь-яких спеціальних методів своїх класів, ні шляхом аудиту сайту для викликів на відповідність деякому посібнику зі стилю "без посилань".
Проблема в житті полягає в основній безпеці пам'яті. Звичайно, незаконно використовувати посилання, коли термін дії посилання закінчився. Але дуже просто забути про час життя, коли ви зберігаєте посилання в об'єкті, зокрема, коли цей об'єкт переживає поточну область. Система типу C ++ не може цього пояснювати, оскільки вона взагалі не моделює життя об'єкта.
std::weak_ptr
Смарт - покажчик робить власність кодування семантики , аналогічну просте посилання, але вимагає, щоб посилання об'єкт управляється через shared_ptr
, тобто є лічильник посилань. Це не абстрагування з нульовою вартістю.
Хоча C ++ має систему const, вона не відстежує, чи може об'єкт бути модифікована, але відстежує, чи може об'єкт бути модифікований за допомогою цієї конкретної посилання . Це не дає достатніх гарантій для "безстрашної одночасності". Навпаки, Руст гарантує, що якщо є активна змінна посилання, яка є єдиною посиланням ("Я єдиний, хто може змінити цей об'єкт"), а якщо є незмінні посилання, то всі посилання на об'єкт не змінюються («Поки я можу читати з об’єкта, ніхто не може його змінити»).
У C ++ ви можете спокуситись захистити доступ до об'єкта за допомогою інтелектуального вказівника з мютекс. Але, як обговорено вище, як тільки ми маємо посилання, це може уникнути очікуваного терміну експлуатації. Тому такий розумний покажчик не може гарантувати, що це єдина точка доступу до керованого об'єкта. Така схема може фактично спрацювати на практиці, оскільки більшість програмістів не хочуть саботажу, але з точки зору типової системи це все ще є абсолютно невідомим.
Загальна проблема з розумними покажчиками полягає в тому, що вони є бібліотеками, що лежать на основі основної мови. Набір основних функцій мови дозволяє цим розумним покажчикам, наприклад, std::unique_ptr
конструкторам потреб рухатися. Але вони не можуть виправити недоліки в основній мові. Здатність неявно створювати посилання під час виклику функції та мати звисаючі посилання разом означають, що основна мова C ++ не є голосною. Неможливість обмеження змінних посилань однією означає, що C ++ не може гарантувати безпеку проти гоночних умов з будь-яким видом одночасності.
Звичайно, багато в чому С ++ та Іржа схожіші, ніж вони не схожі, зокрема щодо їхніх понять про статично визначені життєві періоди. Але хоча можна записати правильні програми C ++ (за умови, що жоден із програмістів не помилиться), Rust гарантує коректність щодо обговорюваних властивостей.