Наследование от std :: vector

0

В настоящее время я создаю класс, который должен быть получен из std :: vector. Я понимаю, что, вероятно, это плохо, но я должен. Теперь мой вопрос заключается в том, как вы получаете доступ к созданному вектору в функциях-членах, чтобы сделать сам класс доступным как обычный вектор целых чисел? Например, я ищу эквивалент myVector.at(0), чтобы вернуть первый член в векторе. Кроме того, размер вектора всегда должен быть 6. Вот код, который у меня есть до сих пор:

class aHistogram : public vector<int>
{
public:
    aHistogram(); //default constructor for histogram class
    void update(int face); //Function to update histogram
    void display(int maxLengthOfLine); //Displays histogram to the scale of maxLengthOfLine using    x's
    void clear();//Function to clear histogram bin counts
    int count(int face) const; // Function to return number of times a face has appeared
private:
    int numx, m, j; //Variables used in functions
};

#endif

Функция, требующая доступа к классу, ниже, я знаю, что нет вектора, называемого "myVector", но то, что я потерял, является эквивалентным синтаксисом, позволяющим выполнить операцию.

void aHistogram::clear() 
{
    //Clears bin counts to 0
    myVector.at(0) = 0;
    myVector.at(1) = 0; 
    myVector.at(2) = 0;
    myVector.at(3) = 0;
    myVector.at(4) = 0;
    myVector.at(5) = 0;
}
  • 0
    @ πάνταῥεῖ Это не дубликат этого вопроса. Этот вопрос касается плюсов и минусов наследования от стандартных типов библиотек и от того, какие типы предназначены для наследования. ОП здесь задает простой вопрос синтаксиса.
  • 0
    Используйте функции-члены vector как будто они определены вашим классом. Вам нужно только явно квалифицировать вызовы, если ваш класс определяет функцию-член, которая уже существует в vector интерфейсе, например, clear() . В этом случае вы можете использовать vector<int>::clear(); , Например: coliru.stacked-crooked.com/a/d3cec10a471438eb
Показать ещё 4 комментария
Теги:
visual-c++
vector
inheritance
subclass

3 ответа

2
Лучший ответ

Если рассматриваемая функция не переопределена в производном классе, вы можете просто вызвать ее:

void HistoGram::clear()
{
    at( 0 ) = 0;
    //  ...
}

Это справедливо и для операторов, но вам придется использовать (*this) в качестве левого оператора:

void HistoGram::clear()
{
    (*this)[0] = 0;
    //  ...
}

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

void HistoGram::clear()
{
    std::vector<int>::at( 0 ) = 0;
    //  ...
}

или нарисуйте этот указатель на тип базового класса:

void HistoGram::clear()
{
    (*static_cast<std::vector<int>*>( this ))[0] = 0;
    //  ...
}

Но вы уверены, что хотите получить наследование? Вы указываете, что размер вектора всегда должен быть 6. Нет никакого способа гарантировать, что использование публичного наследования; по крайней мере, вам нужно частное наследование, а затем using объявления для операций, которые вы хотите поддерживать. (У меня есть несколько случаев, когда мне нужен ограниченный std::vector подобный этому, который я реализовал с использованием частного наследования. И иногда функции пересылки, когда, например, я хотел выставить только версию const функция).

Также: очень, очень мало случаев, когда std::vector<>::at подходит. Вы уверены, что не хотите [], с проверкой границ, которую вы получаете в большинстве современных реализаций.

  • 0
    Спасибо! Я определенно хотел приват.
0

Об этом: размер вектора всегда должен быть 6.

Вероятно, вы хотите запретить некоторые функции пользователю этого класса. Например

  • вектор :: push_back
  • вектор :: pop_back
  • вектор :: вставка

являются функциональными возможностями, которые могут изменять размер вектора.

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

class aHistogram : public vector<int>
{
public:
    aHistogram(){};

private:

    vector<int>::push_back;
    vector<int>::pop_back;
    vector<int>::insert;

    int numx, m, j;
};
  • 0
    Если сделать некоторые функции частными, то это не будущее, но что, если в будущий стандарт или реализацию будет добавлено больше изменяемых функций? Безопаснее наследовать и делать то, что разрешено, явным.
  • 0
    Если aHistogram связан со ссылкой на vector<int> то все функции vector<int> доступны напрямую. Т.е. это не очень хорошее решение. Обычно производный класс может существенно открыть доступ к вещам, но он не может значимо ограничить доступ.
0

Вместо вывода из std::vector в этом случае содержится одно (как элемент данных).

Проблема с получением заключается в том, что тогда можно рассматривать экземпляр Histogram как только std::vector, делая вещи, которые недействительны предположения о значениях добавленных элементов данных.

В более техническом жаргоне с деривацией класса у вас нет гарантированного инварианта класса выше того, который предоставляется std::vector.

Как общее правило, подумайте о члене данных перед наследованием класса.

Иногда наследование - это вещь, даже наследование от стандартных классов контейнеров библиотеки (например, std::stack предназначен для наследования), но не в этом случае.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню