Метод сеттера и геттера для карты - PullRequest
1 голос
/ 02 марта 2011
string var;

void setvar(string ivar)
{
    var=ivar;
}

string getVar() const
{
    return var;
}

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

std :: map varmap;

Ответы [ 4 ]

2 голосов
/ 02 марта 2011

Вы можете написать метод получения или установки для поля, равного std::map, так же, как и любое другое поле - просто получите метод получения возвращающего значения std::map, и установщик может принять std::map.

Конечно, если у вас есть поле std::map, в котором вы пытаетесь использовать методы получения и установки, это может означать, что существует лучший способ структурировать программу.Можете ли вы предоставить более подробную информацию о том, что вы пытаетесь сделать?

РЕДАКТИРОВАТЬ: Ответ выше для немного другого вопроса, чем тот, который вы задали.Похоже, что вас интересует:

Учитывая класс с std::map в качестве члена данных, напишите функцию для установки заданной пары ключ / значение и функцию для возврата значениясвязан с данным ключом.

Логика установки для этого не слишком сложна - вы просто пишете функцию, которая принимает ключ и значение и связывает ключ со значением.Например:

void put(const string& key, const string& value) {
    varmap[key] = value;
}

Написание геттера сложнее, потому что нет гарантии, что есть значение, связанное с конкретным ключом.Когда это происходит, у вас есть несколько вариантов.

  1. Вы можете вернуть значение дозорного .Например, вы можете вернуть пустую строку, если данное значение нигде не хранится на карте.Это делает код для использования функции более легким для чтения, но рискует использовать недопустимое значение в коде.
  2. Вы можете выдать исключение. Это было бы хорошо, если оно представляет серьезную ошибку дляданное значение не существует.Это имеет тот недостаток, что если вы ищете значение, вам всегда нужно try / catch логика, чтобы избежать распространения ошибок.
  3. Вы можете связать значение по умолчанию с ключом,затем передайте это обратно. Если вы пишете программу, которая представляет музыкальную библиотеку, например, вы можете вернуть «(нет)» или «(неизвестно)», если вы попытались найти исполнителя для песнинапример, по которым у вас нет данных.

Ни один из этих подходов не работает лучше всего, и вам нужно подумать, какой из них наиболее соответствует вашим конкретным обстоятельствам.

1 голос
/ 02 марта 2011

Записи в std::map<Key, Value> должны иметь ключ и значение. Обычный способ их получения и настройки:

my_map[a_key] = new_value;   // set

do_something_with(my_map[a_key]);    // get and use...

Если вы хотите добавить новые функции, они, вероятно, не будут выглядеть так, как вы предлагаете, потому что:

  • вашему set присваивается только один параметр, несмотря на необходимость ключа и значения (по общему признанию, вы могли бы принять некоторые соглашения, такие как разделение первых ':' или '=') и
  • функция get () не предоставляет никакой клавиши.

Вместо этого вы можете получить что-то более похожее на:

void set(const Key&, const Value&);
std::string get(const Key&) const;

Но даже если у вас есть для этого права на запись, вам не следует добавлять это непосредственно в заголовочный файл карты - все программы на С ++, скомпилированные на этом компьютере, будут совместно использовать этот файл и не будут ожидать его изменения. Любая небольшая ошибка может вызвать проблемы, и если вы отправите свою программу на другой компьютер, вы не сможете скомпилировать ее там, не сделав подобную модификацию - если этот компьютер использует другой компилятор C ++, необходимые детали этой модификации могут немного отличаться тоже.

Таким образом, вы можете написать свой собственный (предпочтительно шаблонный) класс, который наследуется от (наследует) или содержит (композицию) std :: map, предоставляя ваши функции в вашем пользовательском классе. Решение на основе наследования проще и лаконичнее написать:

template <typename Key, typename Value>
struct My_Map : std::map<Key, Value>
{
    My_Map(...); // have to provide any non-default constructors you want...

    void set(const Key& key, const Value& value) { operator[](key) = value; }

    // if you want entries for non-existent keys to be created with a default Value...
    Value& get(const Key& key) { return operator[](key); }

    --- OR ---

    // if you want an exception thrown for non-existent keys...
    Value& get(const Key& key) { return at(key); }
    const Value& get(const Key& key) const { return at(key); }
};

Это немного опасно, если вы планируете передавать My_Maps по указателю и случайно получить указатель «new My_Map», который позже будет удален как указатель std :: map, как в:

void f(std::map<int, string>* p) { /* use *p */   delete p; }

My_Map<int, string>* p = new My_Map<int, string>;
f(p);

Тем не менее, в большинстве программ нет реальной опасности случайного удаления такой карты, так что продолжайте и сделайте это.

Далее, и именно такое мышление сделает меня непопулярным среди пуристов, боящихся Стандартов, здесь - , потому что My_Map не добавил ни членов данных, ни других баз , std::map<> деструктор , вероятно, выполняет все необходимые операции, даже если это технически неопределенное поведение. Я НЕ поощряю вас игнорировать проблему (и сочтет ее непрофессиональной в работе, требующей устойчивости), но вы можете, по крайней мере, немного отдохнуть немного. Мне было бы любопытно услышать от любого с любым компилятором / настройками, где он явно не работает безопасно.

Если вы используете композицию, вам придется написать свои собственные "функции пересылки", чтобы позволить вам использовать My_Map, например, std :: map, для доступа к итераторам, поиска, удаления, вставки и т. Д. Это боль.

0 голосов
/ 02 марта 2011

Сеттер и геттер для std::map ничем не отличаются, за исключением того, что вам нужно передать необходимые параметры для сеттера. Предположим, что у меня есть struct и переменная-член типа std::map, key типа char и data типа int. Подпись метода будет иметь формат -

  • void setEncode( char* key, int* data, const int& size ); Поскольку для std :: map требуется ключ, данные и размеры этих массивов, которые должны быть переданы. Не зная size, неизвестно, как далеко можно вставить элементы в контейнер.
  • std::map<char, int> getEncode() const ; Ключевое слово const означает, что оно является неизменяемой функцией-членом. Потому что его функциональность - просто возвращать переменную типа std::map.

Пример -

struct myMap
{
    std::map<char, int> encode;
    void setEncode( char* key, int* data, const int& size );
    std::map<char, int> getEncode() const ;
};

void myMap::setEncode( char *key, int* data, const int& size )
{
    int i=0;
    while( i < size )
    {
            encode.insert(std::pair<char, int>(key[i], data[i]));
            ++i ;           
    }
}

std::map<char, int> myMap::getEncode() const
{
    return encode;
}

Результаты IdeOne . Это должно дать вам представление, но также должно следовать общим правилам, предложенным @templatetypedef, @tony.

0 голосов
/ 02 марта 2011

Хотите ли вы установить пару ключ-значение на существующей карте (возможно, это то, что вам нужно) или создать новую карту?

void setvar(string key, int value)
{
    myMap[key] = value;
}

int getVar(string key) const
{
    return myMap[key];
}

где int и string взаимозаменяемы

В последнем случае вам, вероятно, придется использовать все значения карты для установки, а метод получения должен просто возвращать указатель карты.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...