定义3D数组的{set} / getter属性

时间:2016-09-07 09:24:36

标签: c++ arrays multidimensional-array getter-setter

在c ++中,我有一个包含已定义类型的3d数组的类。我需要定义几个值为int的属性,并能够设置和获取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”:

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);

我应该如何定义属性,如struct或typedef或其他东西,然后如何将值设置为我的3D数组成员,例如VOX, 我想将属性设置为Vox本身,而不是内部的点数?可能吗? 它们应该定义为私人还是公共?

3 个答案:

答案 0 :(得分:1)

在第二段代码下面编辑了答案。

好的,首先由@StoryTeller评论,你的向量存储指针;所以你需要使用 - &gt;语法来访问它们指向的对象。

所以你应该设置一个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文字初始化了vox,那么您可以简单地访问和使用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属性。 Voxel类看起来像(原谅我没有提供标题的懒惰)

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

答案 1 :(得分:0)

编辑:看到George Purcell的回答,我可能误解了你的问题,认为这是关于从Voxel课外访问点数......

不过没有删除答案,我仍然把它留在这里,因为你遇到这个问题的任何以后并发现它有用然后 ...

除了StoryTeller指出的指针问题,你还有一点问题:

您可以简单地定义索引运算符,但是此索引运算符将被强制返回对vector<vector<myPoints*>>(少一个向量)或vector<vector<vector<myPoints*>>>::iterator的引用。

然而,这将允许用户修改基础向量,例如, G。清除它们。如果您现在返回const vector或const_iterator,则用户将无法修改存储的值(调用setAttribute ...)。另外,他可以把const扔掉,至少在第一种情况下,然后再做他想做的......

所以你有两个选择:

  1. 您编写了一个明确的getter函数:
    mypoints* getPoints(int x, int y, int z) { return vox[x][y][z]; }
  2. 将向量包装到单独的类中。然后,每个类都可以提供对其底层向量的适当访问,同时防止用户执行非法操作。然后,每个类都将提供自己的operator [],与外部Voxel类相同:
  3. 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()函数) - 这取决于用户应该做什么与你的班级......

答案 2 :(得分:0)

也许这不是你问题的答案,但看起来你是来自C#-kind世界,所以你让我澄清一些事情(我希望你能够重新提出你的问题,这样那么普通的c ++程序员可以理解:)

属性的概念在C ++中完全不同meaning(我认为与您想要实现的内容无关)

在C ++中也没有单独的属性概念(也就是getter / setter)。 相反,您只需编写getSmth()或setSmth(类型arg)成员函数。 它们的目的只是为用户提供对私有成员变量的受控访问。但是,这些功能只是具有特殊功能的常规成员功能。

如果你想获得/设置一个成员变量,请说&#34; tag&#34;从课堂上说&#34; myPoint&#34;你需要定义一个成员函数

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();
}

但是说你有几个getter / setter用于不同的变量。 然后就没办法写

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

并期望编译器弄清楚&#34;哦,他需要得到一个标签成员变量&#34;的值。 在c ++类系统中,只有类成员变量和成员函数可以使用它们 - 一切都很简单:)

有趣的是,您可以参数化任何函数,不仅可以使用值,还可以使用类型。然后,您将能够创建一个功能模板,并根据您设置的类型调用相同功能的不同版本。您可以使用它来定义要调用getter或setter的属性(实际上是成员变量)。

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

但是,我还没有看到它用于定义getter / setter。通常,如果你想得到某些东西&#34;你只需编写一个具体的成员函数GetSomething();