Как правило, я бы сказал, что вы, вероятно, не хотите помещать указатели в свои контейнеры, если только для этого нет веских причин.
Возможные причины для рассмотрения указателей:
- У вас есть
virtual
функции - У вас есть иерархия классов
- Вы не знаете размер объектов, где вы их используете.(Вы можете использовать только указатели или ссылки в этом случае, и у вас не может быть вектора ссылок)
- Ваши объекты очень велики (вероятно, это сравнительный тест)
Самая большая причинане помещать указатели в контейнеры будет означать, что это намного будет проще, чтобы не ошибиться и случайно утечь память.Это особенно верно, когда вы начинаете рассматривать исключения.
Отсутствие указателей в ваших контейнерах значительно упрощает использование STL <algorithms>
, рассмотрим:
#include <vector>
#include <string>
#include <iostream>
#include <iterator>
#include <algorithm>
int main() {
std::vector<std::string> test;
test.push_back("hello world");
std::copy(test.begin(), test.end(),
std::ostream_iterator<std::string>(std::cout, "\n"));
}
В сравнении:
#include <vector>
#include <string>
#include <iostream>
#include <iterator>
#include <algorithm>
int main() {
std::vector<std::string*> test;
// if push_back throws then this will leak:
test.push_back(new std::string("hello world"));
// Can't do:
std::copy(test.begin(), test.end(),
std::ostream_iterator<std::string>(std::cout, "\n"));
// Will now leak too
}
(что я бы никогда делать)
Или, возможно:
#include <vector>
#include <string>
#include <iostream>
#include <iterator>
#include <algorithm>
int main() {
std::vector<std::string*> test;
std::string str("hello world");
test.push_back(&str);
// Can't do:
std::copy(test.begin(), test.end(), std::ostream_iterator<std::string>(std::cout, "\n"));
}
Но семантика этого вызывает у меня чувство дискомфорта - совершенно не ясно, что delete
в другом месте кодабыло бы очень плохо, и вы все еще не можете использовать алгоритмы STL очень удобно, даже если нет утечки.