2013-04-18 1 views
3

У меня есть следующий класс:C++ доступ к значению вектора <int>, который находится внутри класса

class clsUnitArrayIndexToUnitID : public CBaseStructure 
{ 
    private: 
     std::vector<int> m_content; 
     long m_size; 
    protected: 
     void ProcessTxtLine(string line); 
    public: 
     clsUnitArrayIndexToUnitID(); 
     std::vector<int>* Content; 
     long Size(); 
}; 

Я хотел бы получить доступ к значениям из вне класса, например, так:

int iUnitID = m_MyClass.Content()[12]; 

Однако C++ говорит мне, что мне нужно использовать тип точки-функции. Я не уверен, что это точно.

Кроме того, если кто-то видит какой-либо недостаток в моем коде, скажите, пожалуйста.

+0

'Content' указатель на вектор. Вы не можете назвать это функцией. – juanchopanza

ответ

6

Изменить его функции (настроить const для ваших нужд)

public: 
    const std::vector<int>& Content() const { return m_content; } 

и использовать, как вы описали, или разыменования указателя (небезопасно?) В любом случае:

m_MyClass.Content->at(12); 
(*m_MyClass.Content).at(12); 
(*m_MyClass.Content)[12]; 
+0

Я изменил свой код в соответствии с вашими предложениями, но C++ теперь говорит мне: «clsUnitArrayIndexToUnitID не имеет перегруженного оператора элемента» -> '. – tmighty

+0

Это потому, что ответ помещает разыменование в неположенное место. 'M_MyClass.' было в порядке; [] 'является проблемой. – Angew

+0

@elmes Не могли бы вы исправить свой ответ? Должен быть m_MyClass.Content() [12], я думаю. – tmighty

1

Изменить определение следующим образом:

const std::vector<int>* Content() const { 
     return &m_content; 
} 

Первый сопзЬ ключевое слово не является необходимым, но второй один указывает, что метод не должен и не модифицирует экземпляр.

4

Вместо того, выставляя вектор, вы можете предоставить операторам с индексированным доступом вашего класса:

class clsUnitArrayIndexToUnitID : public CBaseStructure 
{ 
public: 
    int& operator[](unsigned int i) {return m_content[i];} 
    const int& operator[](unsigned int i) const {return m_content[i];} 
.... 
}; 

th ан

int iUnitID = m_MyClass[12]; 
+0

Почему вы сделали две перегрузки '[]'? Как программа отличает, какой из них использовать? Или вы просто указали вариант const, -конвой вариант? – akristmann

+3

@akristmann, если класс использовался через const (reference), тогда всегда будет вызван метод secound. – emesx

+0

Почему return 'const int &' over 'const int'? – emesx

0

Обеспечить способ обертки для извлечения содержимого или оператора перегрузки [], как предложенное juanchopanza.

class clsUnitArrayIndexToUnitID : public CBaseStructure 
{ 
    private: 
     std::vector<int> m_content; 
     long m_size; 
    protected: 
     void ProcessTxtLine(string line); 
    public: 
     clsUnitArrayIndexToUnitID(); 
     //std::vector<int>* Content; 

     int GetContent(int index) { 
     int retValue = INVALID_CONTENT 
     if(index >=0 && index<m_content.size()) 
      retValue = m_content[index]; 
     return retValue; 
     }   

     long Size(); 
}; 

И использовать его как

int iUnitID = m_MyClass.GetContent(12); 
+0

Мне это нравится, но мое приложение очень сильно говорит о скорости, поэтому любая проверка индекса будет плохой для меня. – tmighty

+0

Затем просто «return m_content [index];» из GetContent (int). При включенной оптимизации компилятор будет использовать методы GetContent()/operator []. Нет необходимости в каких-либо указателях как таковых. – Arun

2

Чтобы ответить на конкретный вопрос, вы должны сделать это:

(*m_MyClass.Content)[12] 

Или это:

m_MyClass.Content->at(12); //note that the semantics is slightly different - at() checks boundaries, [] does not 

Однако дело вы должны действительно сделать, вероятно, подумайте, что вы r дизайн. Почему у вашего класса есть открытый элемент данных указателя типа на контейнер? Если это всегда будет указывать на m_content, вы можете также сделать m_content общественностью и сэкономить на хлопот.

Общая идея частных членов данных заключается в предоставлении доступа на основе семантики, так что ваша функция будет публиковать функции, такие как «вставить в вектор», «получить элемент из вектора» и т. Д., Поскольку его семантика диктует. Или, например, вы можете предоставить функцию доступа только для чтения, возвращающую const std::vector<int>&, и оставить доступ к модификации специальным функциям-членам.

Если вы предоставляете обертку, дающую прямой неконстантный доступ, это вряд ли обертка (она всегда должна быть подкреплена чем-то).

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

0

Вы можете вернуть ссылку вместо указателя:

std::vector<int> m_content(UNITS_MAX_SIZE); 

const std::vector<int> &clsUnitsUnitIDToArrayIndex::Content() const 
{ 
    return m_content; 
}