2016-09-07 2 views
0

В C++ у меня есть класс, который содержит 3D-массив определенного типа. Мне нужно определить несколько атрибутов, которые имеют значение int и смогут устанавливать и получать атрибуты для 3d-массива.Определить атрибуты setter/getter для 3D-массива

//header; 
    class Voxel 
    { 
     private: 
     vector< vector < vector < myPoints* > > > Vox; // 3D array 
     public: 
     //... 
    }; 

    //Here is the constructor and methods of the class: 
    Voxel::Voxel(myType var1; double var2) 
    { 
    // this is constructor 

    } 

Например, мне нужно, чтобы определить «Атрибуты», как это которые имеют Int значения:

Attributes: 
LabelTag; // Vox tag e.g. an int tag=2 
NumberofPoints; // Vox nr of containing points e.g. int nr=5 


Vox.setAttribute(LabelTag tag, Value 2); 
Vox.setAttribute(NumberofPoints nr, Value 5); 

int tag  = Vox.getAttribute(LabelTag); 
int nrofpoints = Vox.getAttribute(NumberofPoints); 

Как следует определить атрибуты, так как структура или как ЬурейеЕ или что-то другое, а затем, как могу ли я установить значения для моих трехмерных элементов массива, например Vox, Я хочу установить атрибуты самого Vox, а не точки внутри? Является ли это возможным? И должны ли они определяться как частные или публичные?

+5

Вы храните указатели, поэтому для доступа к ним вы используете синтаксис «arrow». Vox [i] [j] [k] -> getAttribute() ' – StoryTeller

+0

Пожалуйста, сообщите нам, что такое использование меток LabelTag и NumberOf Points? Вы можете сохранить одну точку на вектор, так что у вас есть 3 точки в одном 3D-массиве. – pospich0815

+0

@ pospich0815, это и попытка умного (возможно) использования отправки тега. Специализация шаблона может быть лучше 'getAttribute

ответ

1

Отредактированный ответ ниже второго блока код.

Хорошо, во-первых, как прокомментировал @StoryTeller, ваш вектор хранит указатели; поэтому вам нужно будет использовать синтаксис -> для доступа к объекту, на который они указывают.

Поэтому вы должны, вероятно, настроить класс myPoints, поскольку структуры обычно не видны (структуры в C++ - это то же самое, что и класс, за исключением модификатора доступа по умолчанию к их свойствам и функциям, является общедоступным). Я предположил бы, что этот класс, чтобы посмотреть что-то вроде

class myPoints // you should probably split this into a header and cpp 
{ 
    int tag; 
    int noOfPoints; 

    myPoints() : tag(0), noOfPoints(0) // construct with whatever values, you can pass your own 
    {} 

    void setNoOfPoints(noOfPoints) 
    { 
     this->noOfPoints = noOfPoints; 
    } 

    void setTag(tag) 
    { 
     this->tag = tag; 
    } 

    int getNoOfPoints(){ return noOfPoints; } 
    int getTag(){ return tag; } 
}; 

Предполагая, что вы инициализирован вокс с некоторыми * MyPoints литералы вы можете просто получить доступ и использовать MyPoints объекты следующим

int tag = Vox.at(i).at(j).at(k)->getTag(); 
int noOfPoints = Vox.at(i).at(j).at(k)->getNoOfPoints(); 

Vox.at(i).at(j).at(k)->setNoOfPoints(6); 
Vox.at(i).at(j).at(k)->setTag(6); 

Оставляя выше ответ, как и с ответом @ Aconcagua, вы можете найти его полезным в будущем.

В любом случае, я думаю, что я немного понимаю, что вы пытаетесь сделать, учитывая код, который вы уже написали, как сказал @StoryTeller, вы можете просто использовать свой класс Voxel для хранения тегов и свойств noOfPoints для каждого вектора , Класс Воксельный будет выглядеть примерно так (простите мою лень в не обеспечивает заголовок)

class Voxel 
{ 
private: 
    vector< vector < vector < myPoints* > > > Vox; 

    int tag; 
    int noOfPoints; 
public: 
    Voxel() : tag(0), noOfPoints(0) // construct with whatever values, you can pass your own 
    {} 

    vector< vector < vector < myPoints* > > >& getVox(){ return Vox; } //Ignore my shitty naming scheme, you can use this to set or get elements 

    void setNoOfPoints(noOfPoints) 
    { 
     this->noOfPoints = noOfPoints; 
    } 

    void setTag(tag) 
    { 
     this->tag = tag; 
    } 

    int getNoOfPoints(){ return noOfPoints; } 
    int getTag(){ return tag; } 
}; 

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

//A new vector of voxels 

vector<Voxel> voxels; 

voxels.push_back(Voxel); // this only needs to be a 1d array, you can construct each voxel however you like and add as many as you like 

//settting the tag for the first element 

voxels[0].setTag(0); 

//getting the tag for the first element 

int tag = voxels[0].getTag(); 

// manipulating the contained vector 

voxels[0].getVox().at(i).at(j).at(k) = //whatever you are storing in your vector 
+0

этот ответ близок к тому, что мне нужно, но по мере того, как я редактировал вопрос, можно ли присвоить эти атрибуты самому Vox, а не внутренним. Поскольку myPoints могут иметь разные значения для каждой точки, но Vox, который содержит эти myPoints, может получить одно значение за «Атрибут». Или представьте, что некоторые из Vox пустые, но все же я могу назначить им некоторые атрибуты. – Bruce

+0

Возможно! Infact, как было указано, вы были на правильных линиях с классом Voxel, я отредактировал свой ответ, надеюсь, что это поможет :) – George

+0

Спасибо, я внедрил ваш код, и он очень близок к тому, что я ищу. Просто я не понимаю одну важную вещь, когда я назначаю, например. "tag attribute" с 'i_Voxel.setTag (6)' он устанавливает его к чему? !! Я предполагаю экземпляр «Voxel», но как я должен знать, к какому вектору Vox он был установлен. Предположим, что у меня есть цикл через все векторы и вы хотите установить для каждого вектора тег. Не могли бы вы объяснить, как это работает? – Bruce

0

Edit: Видя ответ Джорджа Перселла, я бы понял вас вопрос, думал, что это было о доступе точки из-за пределы класса Voxel ...

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


Помимо проблемы рассказчик указатель уже отмечалось, у вас есть немного Задача:

Вы можете просто определить оператор индекса, но этот оператор индекса будет принудительно возвращать ссылку на vector<vector<myPoints*>> (один вектор меньше) или vector<vector<vector<myPoints*>>>::iterator.

Это, однако, позволит пользователю изменять базовые векторы, e. г. очищая их. Если вы теперь вернули const vector или const_iterator, пользователь не сможет изменить сохраненное значение (вызывая setAttribute ...). Кроме того, он может бросить Конст прочь, по крайней мере, в первом случае, а затем снова делать то, что он хотел ...

Так у вас есть два варианта:

  1. Вы пишете явную функцию геттер:
    mypoints* getPoints(int x, int y, int z) { return vox[x][y][z]; }
  2. Вы переносите векторы в отдельные классы. Затем каждый класс может обеспечить соответствующий доступ к его базовому вектору и в то же время запретить пользователю делать незаконные вещи. Каждый из этих классов будет затем предоставить свой собственный оператор [], то же самое будет делать ваш внешний класс Voxel:

class Voxel 
{ 
public: 
    class Points1D 
    { 
     vector<myPoints*> points; 
    public: 
     myPoints* operator[](unsigned int index) { return points[index]; } 
    }; 
    class Points2D 
    { 
     vector<Points1D> points; 
    public: 
     Points1D& operator[](unsigned int index) { return points[index]; } 
    }; 
    Points2D& operator[](unsigned int index) { return points[index]; } 
private: 
    vector<Points2D> points; 
}; 

Если вы хотите, чтобы иметь возможность перебрать ваших классов, то вам должен также предоставить соответствующие итераторы и, возможно, другие вещи (например, функцию size()) - в зависимости от того, что пользователь сможет делать с вашими классами ...

0

Может быть, это не ответ на ваш вопрос, но это выглядит, как вы пришли из C# -kind мира, поэтому позвольте мне прояснить некоторые вещи (я надеюсь, что тогда вы будете иметь возможность переформулировать ваш вопрос, так что обычный программист на С ++ мог бы понять :)

Понятие атрибутов полностью отличается от meaning в C++ (я думаю, не имеет отношения к тому, что вы хотите реализовать)

Также нет никаких понятий свойств (ака геттеры/сеттеры) в C++. Вместо этого вы просто пишете функции getSmth() или setSmth (type arg). Их целью является предоставление пользователю контролируемого доступа к частным переменным-членам. Однако эти функции являются просто регулярной функцией-членом с теперь специальными способностями.

Если вы хотите получить/установить переменную член сказать: «тег» из класса говорят «MyPoint» вам необходимо определить функцию-член

class myPoint 
{ 
private: 
    int tag; 
//... 
public: 
    int GetTag(); 
    { 
     return tag; // return this->tag; 
    } 

    void SetTag(int t) 
    { 
     tag = t; 
    } 
} 

Тогда вы можете написать

int main() 
{ 
    vector<vector<vector<myPoint*>>> Vox; 
    Vox[1][2][3]->SetTag(10); 
    cout << Vox[1][2][3]->GetTag(); 
} 

Однако скажем, у вас есть несколько геттеров/сеттеров для разных переменных. Тогда нет никакого способа, чтобы написать

Vox[1][2][3]->GetAtribute(tag); 

и ожидать, что компилятор, чтобы выяснить, что «ой, он должен получить значение переменной-члена тега». В системе класса C++ существуют только переменные-члены и функции-члены, которые могут их использовать - все так просто:

Интересно, что вы можете параметризовать любую функцию не только со значениями, но и с типами. Затем вы сможете создать шаблон функции и вызвать разные версии одной и той же функции в зависимости от того, какой тип вы установили. Вы можете использовать это, чтобы определить, для какого атрибута (действительно, переменной-члена) вы хотите назвать геттер или сеттер.

// LableTag is a class defined globally and GetAttribute() is a member 
//template function 
int i = Vox[1][2][3]->GetAttribute<LableTag>(); 

Однако, я не видел, чтобы он использовался для определения геттеров/сеттеров. Обычно, если вы хотите «получить что-то», вы просто пишете конкретную функцию-член GetSomething();

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