#c #class #pointers #vector #stdvector
#c #класс #указатели #вектор #stdvector
Вопрос:
У меня есть 2D-таблица строк (с использованием вектора STL), и я пытаюсь изменить ее так, чтобы таблица представляла собой вектор указателей на векторы строк. Я знаю, что для этого потребуется изменить конструктор, чтобы строки создавались динамически, а указатели на строки вставлялись в таблицу, но я не уверен, как приступить к созданию этой таблицы в первую очередь.
В моем файле .h:
class StringTable
{
public:
StringTable(ifstream amp; infile);
// 'rows' returns the number of rows
int rows() const;
// operator [] returns row at index 'i';
const vector<string> amp; operator[](int i) const;
private:
vector<vector<string> > table;
};
В моем файле .cpp:
StringTable::StringTable(ifstream amp; infile)
{
string s;
vector<string> row;
while (readMultiWord(s, infile)) // not end of file
{
row.clear();
do
{
row.push_back(s);
}
while (readMultiWord(s, infile));
table.push_back(row);
}
}
int StringTable::rows() const
{
return table.size();
}
const vector<string> amp; StringTable::operator[](int i) const
{
return table[i];
}
Я чувствую, что это, вероятно, довольно простое переключение, но у меня нет большого опыта использования векторов, и я не уверен, с чего начать. Любые рекомендации приветствуются!
Комментарии:
1. Зачем вам нужен вектор указателей? Это звучит как ужасная идея.
2. @BrendanLong Это C / C !
3. Почему у вас есть
while (readMultiWord(s, infile))
внутриwhile (readMultiWord(s, infile))
? Возвращается ли онfalse
в конце строки или что-то в этом роде?4. @muntoo Да, он считывает строки из таблицы, в которой каждое поле разделено символом s. Когда программа читает в word, она отодвигает s, а затем, когда она достигает конца строки, она отодвигает строку слов.
Ответ №1:
Похоже, вы пытаетесь создать некоторую форму многомерного вектора. Рассматривали ли вы возможность использования boost? http://www.boost.org/doc/libs/1_47_0/libs/multi_array/doc/user.html
Комментарии:
1. Если вы действительно хотите создать свой собственный, эффективный C от Meyers охватывает именно этот сценарий. TLDR: вместо того, чтобы взламывать вещи с помощью operator[], просто создайте функцию «string getElement (int row, int col)» и «SetElement (int row, int col, const string amp;value);»
Ответ №2:
ОК, самый простой способ сделать это с помощью typedef. Также кажется, что вы используете предложения ‘using’ в своих файлах заголовков — вы никогда не должны этого делать.
class StringTable
{
public:
typedef std::vector<std::string> Strings_t;
std::vector<Strings_t *> table;
};
Не забывайте при добавлении a теперь вам нужно будет выделить память, т.е.:
StringTable tbl;
StringTable::Strings_t *data_ptr=new StringTable::Strings_t;
data_ptr->push_back("foo");
data_ptr->push_back("bar");
tbl.table.push_back(data_ptr);
[Исправлено]
Комментарии:
1. Как
typedef
сделать это более понятным? Даже в вашем тривиальном примере это вызывает проблемы (Strings_t
vsString_t
).2. Да, @Paul, не используй
using namespace std;
внутри своих заголовочных файлов… На самом деле, я бы не стал использовать его нигде .3. @Brendan — а) Я должен был скомпилировать (String_t vs Strings_t) — это опечатка, а также я забыл пространство имен класса
4. Почему вы используете
new
? Это просто запрос на утечку памяти. И если вы действительно хотите использовать указатели без причины, исправьте эту строкуtbl.table.push_back(amp;data_ptr);
и используйтеdelete dataptr;
.5. Использование new совершенно нормально — оно НЕ требует утечки памяти — и это значительное увеличение производительности. Пожалуйста, не избегайте языковых функций, потому что вы их боитесь — используйте их правильно, и они отлично работают.