Объявление вектора указателей на вектор строк

#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 vs String_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 совершенно нормально — оно НЕ требует утечки памяти — и это значительное увеличение производительности. Пожалуйста, не избегайте языковых функций, потому что вы их боитесь — используйте их правильно, и они отлично работают.