В настоящее время я создаю класс, который должен быть получен из 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;
}
Если рассматриваемая функция не переопределена в производном классе, вы можете просто вызвать ее:
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
подходит. Вы уверены, что не хотите []
, с проверкой границ, которую вы получаете в большинстве современных реализаций.
Об этом: размер вектора всегда должен быть 6.
Вероятно, вы хотите запретить некоторые функции пользователю этого класса. Например
являются функциональными возможностями, которые могут изменять размер вектора.
Вы можете добиться этого, сделав такие функции частными членами в дочернем классе:
class aHistogram : public vector<int>
{
public:
aHistogram(){};
private:
vector<int>::push_back;
vector<int>::pop_back;
vector<int>::insert;
int numx, m, j;
};
aHistogram
связан со ссылкой на vector<int>
то все функции vector<int>
доступны напрямую. Т.е. это не очень хорошее решение. Обычно производный класс может существенно открыть доступ к вещам, но он не может значимо ограничить доступ.
Вместо вывода из std::vector
в этом случае содержится одно (как элемент данных).
Проблема с получением заключается в том, что тогда можно рассматривать экземпляр Histogram
как только std::vector
, делая вещи, которые недействительны предположения о значениях добавленных элементов данных.
В более техническом жаргоне с деривацией класса у вас нет гарантированного инварианта класса выше того, который предоставляется std::vector
.
Как общее правило, подумайте о члене данных перед наследованием класса.
Иногда наследование - это вещь, даже наследование от стандартных классов контейнеров библиотеки (например, std::stack
предназначен для наследования), но не в этом случае.
vector
как будто они определены вашим классом. Вам нужно только явно квалифицировать вызовы, если ваш класс определяет функцию-член, которая уже существует вvector
интерфейсе, например,clear()
. В этом случае вы можете использоватьvector<int>::clear();
, Например: coliru.stacked-crooked.com/a/d3cec10a471438eb