У меня есть свой класс, который хранит коллекцию объектов с их именами
template <typename T>
class MyVector
{
private:
vector<T> objects;
vector<string> m_names;
size_t m_ref_ptr;
public:
MyVector()
{
m_ref_ptr = 1;
}
MyVector(const MyVector& other) : objects(other.objects),
m_ref_ptr(other.m_ref_ptr),
m_names(other.m_names)
{
m_ref_ptr++;
}
void push_back(const T& obj, const std::string& name)
{
copy_names();
objects.push_back(obj);
m_names.push_back(name);
}
void copy_names()
{
if (m_ref_ptr == 1)
{
return;
}
size_t temp_ref_ptr = 1;
vector<string> temp_names(m_names);
m_ref_ptr--;
m_ref_ptr = temp_ref_ptr;
m_names = temp_names;
}
Задача состоит в том, чтобы использовать идиому «копировать при записи» для эффективности имен.
Я что-то пробовал, но я не уверен, зачем нам это нужно, если в моем классе все работает нормально без этой копии на записи, я читал об этой идиоме: основная идея: мы создаем реальную копию, когда мы хотим написать что-то, с целью написать.
Мой код действительно прост. Пожалуйста, дайте мне подсказку, как это сделать в моем коде?
Извините, я не могу добавить к комментариям, потому что у меня еще недостаточно очков репутации, поэтому я пишу это как ответ:
Дано m_names это станд :: shared_ptr, в copy_names (и при условии используя пространство имен std ты пишешь:
if (m_names.use_count() > 1) { // this is c++11
m_names = make_shared<vector<string>>(*m_names);
}
Вы можете бросить m_ref_ptr член, потому что станд :: shared_ptr будет следить за этим. В конструкторе нужно будет создать пустой вектор:
MyVector()
{
m_names = make_shared<vector<string>>());
}
Кстати, в вашем коде m_ref_ptr не менял счетчик ссылок в исходном объекте, т.е. если бы вы сделали:
MyVector a;
...
MyVector b = a;
тогда у тебя все равно будет a.m_ref_ptr == 1. станд :: shared_ptr должным образом заботится об этом.
Других решений пока нет …