2013-03-13 4 views
0

У меня есть следующий класс.std vector, копирование структуры данных

class Row 
{ 
    Table* parent_table; 
    Row(Table* construct); 
} 
class Table 
{ 
    std::vector<Row>; 
} 

Я создаю std::vector<Table> test;, и в цикле я создаю объекты таблицы и оттеснить их на тест-вектор. Проблема в том, что я теряю таблицу * внутри каждой строки. Мне нужен указатель, поэтому, когда я повторяю свои строки, я знаю, к какой таблице они принадлежат.

Есть ли способ заставить std :: vector, а не копировать объекты, когда их отталкивают назад?

+0

«Проблема в том, что я теряю таблицу * внутри каждой строки». Можете ли вы рассказать об этом, что это значит? Похоже на то, о чем должен заботиться соответствующий конструктор-копир. – jrok

+0

Знаете ли вы, что адреса объектов в 'std :: vector

' могут меняться, как вы 'push_back'? Если вам нужно, чтобы адреса объектов были стабильными, вы не можете хранить их прямо в 'std :: vector' без особого внимания. Тогда мой ответ ниже также применим к 'std :: vector
' - store 'std :: vector >'. – Yakk

ответ

4

Вместо того чтобы хранить в вашем std::vector, магазин std::unique_ptr<Row> или std::shared_ptr<Row>. Они, как правило, достаточны для такого рода вещей (есть более сложные способы, с помощью которых вы можете приблизиться к этому, например, хранить исходные указатели (сложные для обслуживания) или перематывать собственный класс на основе pImpl или писать собственный смарт-указатель с пользовательской семантикой).

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

+0

Yeap с использованием общего указателя - лучший вариант –

1

Push элементы по ссылке или указателю. Вы нажимаете копии, поэтому копирование элемента - это все, что может сделать C++. Я бы лично посоветовал вам использовать вектор указателей, например: std::vector<Row*>

На самом деле более безопасным и чистым способом было бы хранить shared_ptr-s вместо простых указателей, так что вам не нужно иметь дело с управлением памятью , Что-то вроде:

std::vector<std::shared_ptr<Row> >

0

Самым простым решением в этом случае, вероятно, будет хранить итератор в таблицу:

class Row 
{ 
    std:vector<Table>::iterator parent_table; 
    Row(std:vector<Table>::iterator construct); 
} 
+2

'std :: vector

:: iterator' легко недействителен. Я бы посоветовал не хранить такие итераторы, если вы не знаете все правила аннулирования итератора 'std :: vector' и можете гарантировать, что они никогда не произойдут. – Yakk

+0

А ты прав ... даже push_back делает итераторы недействительными, если происходит перераспределение. Спасибо за совет – JSQuareD

1

Вы задаете два несвязанных вопросы. Пожалуйста, не делайте этого в одном сообщении. Один пост - один вопрос. Это облегчает ответ.

ВТОРОЙ:

Есть ли способ заставить зЬй :: вектор, а не копировать объекты, когда они оттеснили?

Другие ответы являются ответом.

ПЕРВЫЙ:

создать тест станд :: вектор ;, и в цикле я создаю объекты таблицы и оттеснить их на тест-вектор. Проблема в том, что я теряю таблицу * внутри строки внутри таблицы. Мне нужен указатель, поэтому, когда я повторяю свои строки, я знаю, к какой таблице они принадлежат.

Скорее всего, ваша ROW не содержит никакой обратной ссылки на таблицу, которая содержит ее. Таким образом, когда вы проходите вокруг вектора строк или самой строки, вы теряете информацию о том, кто ее владеет.Вы должны либо передать a-vector-of-rows вместе с table* owner, либо строку вместе с table* owner, либо вы должны сделать свою строку более интеллектуальной и заставить все строки содержать table* owner (то есть иметь строки, содержащие ссылку на владельца)

Конечно, обратная связь может быть любой формы. Он не должен быть указателем. Вы можете пройти Table&, a shared_ptr<Table>, a string tablename или что-то еще, что поможет вам получить доступ к таблице напрямую или через какого-либо менеджера. Важно то, что либо строка должна содержать это, либо должна быть передана отдельно, но вместе с строками.

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