2014-09-27 3 views
6

У меня вопрос о умных указателях в C++ 11. Я начал смотреть на C++ 11 (обычно в C#) и прочел кое-что о умных указателях. Теперь у меня есть вопрос, действительно ли умные указатели полностью заменяют «старый» стиль указателей, должен ли я всегда использовать их?C++ 11 Использование смарт-указателя

unique_ptr, похоже, решает все проблемы с управлением памятью на C++, или я ошибаюсь?

Например:

std::unique_ptr<GameManager> game (new GameManager()); 

game->Start(); 

Кажется, гораздо умнее:

auto *game2 = new GameManager(); 

game2->Start(); 

delete game2; 

Спасибо, я немного запутался!

+6

Вы не должны использовать их, если нет вопросов о собственности. Например, если что-то владеет игровым менеджером, а что-то еще хочет его использовать (например, полиморфно) и не имеет права голоса или прав на его жизнь, то вы можете рассмотреть передачу ему необработанного указателя. – juanchopanza

+0

Спасибо, теперь более понятно – BendEg

+5

«решить все проблемы» - нет. Однако это решает многое. –

ответ

6

Чтобы ответить на ваш вопрос: да, они решают проблемы управления памятью.

Это считается хорошим стилем, чтобы использовать их как можно больше.

Они устраняют множество возможных ошибок программирования и уменьшают сложность создания правильного кода с помощью указателей.

пойти еще дальше, он считается хорошим, чтобы изменить

std::unique_ptr<GameManager> game (new GameManager()); 

To:

std::unique_ptr<GameManager> game (std::make_unique<GameManager>()); 
+1

Спасибо за ваш быстрый ответ, но что с этим ответом make_unique: http://stackoverflow.com/a/9657991/? – BendEg

+0

@BendEg Это в C++ 14 и широко доступно. –

+0

Хорошо, я прочитаю кое-что о C++ 14, я думал, что это еще не стандарт. (Я использую mvC++) – BendEg

3

В дополнение к единой собственности unique_ptr, есть также ситуации, когда есть общие, или трудно определить право собственности. В этих случаях shared_ptr обеспечивает подсчет ссылок, а последний владелец удаляет референт.

В случаях, когда shared_ptr может быть задействован в сложном эталонном цикле, стандарт также предоставляет weak_ptr.

Все они заменяют место старого auto_ptr.

9

Для показанного использования, в то время как unique_ptr лучше, чем необработанный указатель, поскольку он указывает на принадлежность выделенных ресурсов, вы, вероятно, вообще не должны использовать какой-либо указатель. Вместо того, чтобы просто объявить местный:

GameManager game; 
game.Start(); 

Это может не хватить, если право собственности, возможно, придется дать что-то другое, в то время как право собственности на unique_ptr легко могут быть переданы.

+1

Я поднимаю этот ответ, как он указывает - как еще один комментарий выше, - что очень хорошо можно жить на C++ без каких-либо указателей, помещая объекты в стек. –

+0

Это действительно должен быть принятый ответ.В настоящее время принятый ответ заставляет его звучать так, как выделение кучками локальных объектов предпочтительнее для выделенных стеков, что редко бывает верно. –

3

Нет, не полностью заменяйте все необработанные указатели.

Использование интеллектуальных указателей (unique_ptr, shared_ptr) действительно полезно только для тех указателей, которые владеют и управляют памятью указателя. Однако, если функция принимает указатель в качестве параметра, то вы не хотите передавать права собственности. Функция просто нуждается в доступе к указателю.

void ShowCredits(GameManager* game) // Just use game, don't take ownership. 
{          // A raw pointer here is good. 
    // ... 
} 

void main() 
{ 
    auto game = make_unique<GameManager>(); // game owns the GameManager. 
    game->Start(); 
    ShowCredits(game.get()); 
} 

P.S. Если ShowCredits полагается на игру, всегда действующую (т.он необязательно может иметь значение nullptr), вы можете быть в лучшем случае в этом случае с параметром типа GameManager &.

+6

Вместо того, чтобы проходить по указателю, перейдите по ссылке ShowCredits (GameManager & game); ' –

+0

' main' должен возвращать 'int'. – GingerPlusPlus

Смежные вопросы