2014-12-05 3 views
0

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

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

@ πάνταῥεῖ Это не дубликат этого вопроса. В этом вопросе рассматриваются преимущества/недостатки наследования от стандартных типов библиотек и какие типы предназначены для наследования. ОП здесь задает простой вопрос синтаксиса. – Praetorian

+0

Используйте функции 'vector', как если бы они были определены вашим классом. Вам нужно только явно квалифицировать вызовы, если ваш класс определяет функцию-член, которая уже существует в интерфейсе 'vector', например' clear() '. В этом случае вы можете использовать 'vector :: clear();'. Например: http://coliru.stacked-crooked.com/a/d3cec10a471438eb – Praetorian

+0

@Praetorian Большое спасибо! Работал именно так, как мне было нужно. – Antoninus

ответ

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

Спасибо! Я определенно хотел частного. – Antoninus

0

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

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

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

Как правило, рассмотрите элемент данных перед наследованием класса.

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

0

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

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

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

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

Вы можете achive это путем таких функций частных пользователей в дочернем классе:

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

private: 

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

    int numx, m, j; 
}; 
+0

Выполнение некоторых функций private не является будущим доказательством, хотя, что, если в будущем стандарте или реализации добавляются более изменчивые функции? Безопаснее наследовать в частном порядке и делать то, что разрешено явным. – sjdowling

+0

Если 'aHistogram' привязан к ссылке на' vector ', тогда вся функциональность' vector 'доступна непосредственно. То есть это нехорошее решение. Обычно производный класс может осмысленно открывать доступ к вещам, но он не может существенно ограничить доступ. –

Смежные вопросы