为 3D 数组定义 setter/getter 个属性
Define setter/getter attributes for a 3D array
在 C++ 中,我有一个 class,其中包含一个已定义类型的 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 本身设置属性,而不是里面的点?可能吗?
它们应该定义为私有还是 public?
编辑: 看到 George Purcell 的回答,我可能误解了你的问题,以为是关于从体素外部访问点 class...
虽然我没有删除答案,但我仍然把它留在这里,以防你 运行 在 以后 遇到这个问题并发现它有用 然后...
除了 StoryTeller 已经指出的指针问题,您还有一个小问题:
您可以简单地定义一个索引运算符,但此索引运算符随后将被迫 return 对 vector<vector<myPoints*>>
(少一个向量)或 vector<vector<vector<myPoints*>>>::iterator
的引用。
但是,这将允许用户修改基础向量,例如。 G。清除它们。如果您现在 returned const vector 或 const_iterator,用户将无法修改存储的值(调用 setAttribute...)。此外,他可以放弃 const,至少在第一种情况下,然后再次做他想做的事...
所以你有两个选择:
- 你写了一个明确的getter函数:
mypoints* getPoints(int x, int y, int z) { return vox[x][y][z]; }
- 您将向量包装成单独的 classes。然后每个 class 都可以提供对其底层向量的适当访问,同时防止用户做非法的事情。然后,每个 classes 都会提供自己的运算符 [],就像你的外部 Voxel class:
一样
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;
};
如果你希望能够迭代你的 classes,那么你也必须提供适当的迭代器,并且可能还需要提供其他东西(例如 size() 函数)——这取决于什么用户应该能够使用您的 classes...
在第二个代码块下方编辑了答案。
好的,首先正如@StoryTeller 所评论的那样,您的向量正在存储指针;所以你需要使用 -> 语法来访问它们指向的 object 。
因此,您可能应该设置一个 myPoints class,因为结构并不常见(C++ 中的结构与 class 相同,只是它们的属性和函数的默认访问修饰符是 public).我想象这个 class 看起来像
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 objects
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 class 来保存标签和每个向量的 noOfPoints 属性。体素 class 看起来像(原谅我没有提供 header 的懒惰)
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
也许这不是你问题的答案,但看起来你来自 C#-kind 世界,所以你让我澄清一些事情(我希望你能够重新表述你的问题,以便普通c++程序员都能看懂:)
属性的概念和C++完全不一样meaning(我觉得跟你要实现的东西无关)
C++ 中也没有单独的属性概念(又名 getters/setters)。
相反,您只需编写 getSmth() 或 setSmth(type arg) 成员函数。
它们的目的只是为用户提供对私有成员变量的受控访问。然而,这些函数只是具有特殊能力的常规成员函数。
如果你想get/set一个成员变量说"tag"从class说"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();
}
但是假设您有几个 getters/setter 用于不同的变量。
那就没办法写
Vox[1][2][3]->GetAtribute(tag);
并期望编译器找出 "oh, he needs to get a value of tag member variable"。
在 C++ class 系统中,只有 class 成员变量和可以使用它们的成员函数——一切就这么简单:)
有趣的是,您不仅可以使用值参数化任何函数,还可以使用类型参数化任何函数。然后,您将能够创建一个函数模板,并根据您设置的类型调用同一函数的不同版本。您可以使用它来定义要调用 getter 或 setter.
的属性(实际上是成员变量)
// LableTag is a class defined globally and GetAttribute() is a member
//template function
int i = Vox[1][2][3]->GetAttribute<LableTag>();
但是,我还没有看到它被用于定义 getters/setters。通常如果你想 "get something" 你只需要写一个具体的成员函数 GetSomething();
在 C++ 中,我有一个 class,其中包含一个已定义类型的 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 本身设置属性,而不是里面的点?可能吗? 它们应该定义为私有还是 public?
编辑: 看到 George Purcell 的回答,我可能误解了你的问题,以为是关于从体素外部访问点 class...
虽然我没有删除答案,但我仍然把它留在这里,以防你 运行 在 以后 遇到这个问题并发现它有用 然后...
除了 StoryTeller 已经指出的指针问题,您还有一个小问题:
您可以简单地定义一个索引运算符,但此索引运算符随后将被迫 return 对 vector<vector<myPoints*>>
(少一个向量)或 vector<vector<vector<myPoints*>>>::iterator
的引用。
但是,这将允许用户修改基础向量,例如。 G。清除它们。如果您现在 returned const vector 或 const_iterator,用户将无法修改存储的值(调用 setAttribute...)。此外,他可以放弃 const,至少在第一种情况下,然后再次做他想做的事...
所以你有两个选择:
- 你写了一个明确的getter函数:
mypoints* getPoints(int x, int y, int z) { return vox[x][y][z]; }
- 您将向量包装成单独的 classes。然后每个 class 都可以提供对其底层向量的适当访问,同时防止用户做非法的事情。然后,每个 classes 都会提供自己的运算符 [],就像你的外部 Voxel class: 一样
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;
};
如果你希望能够迭代你的 classes,那么你也必须提供适当的迭代器,并且可能还需要提供其他东西(例如 size() 函数)——这取决于什么用户应该能够使用您的 classes...
在第二个代码块下方编辑了答案。
好的,首先正如@StoryTeller 所评论的那样,您的向量正在存储指针;所以你需要使用 -> 语法来访问它们指向的 object 。
因此,您可能应该设置一个 myPoints class,因为结构并不常见(C++ 中的结构与 class 相同,只是它们的属性和函数的默认访问修饰符是 public).我想象这个 class 看起来像
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 objects
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 class 来保存标签和每个向量的 noOfPoints 属性。体素 class 看起来像(原谅我没有提供 header 的懒惰)
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
也许这不是你问题的答案,但看起来你来自 C#-kind 世界,所以你让我澄清一些事情(我希望你能够重新表述你的问题,以便普通c++程序员都能看懂:)
属性的概念和C++完全不一样meaning(我觉得跟你要实现的东西无关)
C++ 中也没有单独的属性概念(又名 getters/setters)。 相反,您只需编写 getSmth() 或 setSmth(type arg) 成员函数。 它们的目的只是为用户提供对私有成员变量的受控访问。然而,这些函数只是具有特殊能力的常规成员函数。
如果你想get/set一个成员变量说"tag"从class说"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();
}
但是假设您有几个 getters/setter 用于不同的变量。 那就没办法写
Vox[1][2][3]->GetAtribute(tag);
并期望编译器找出 "oh, he needs to get a value of tag member variable"。 在 C++ class 系统中,只有 class 成员变量和可以使用它们的成员函数——一切就这么简单:)
有趣的是,您不仅可以使用值参数化任何函数,还可以使用类型参数化任何函数。然后,您将能够创建一个函数模板,并根据您设置的类型调用同一函数的不同版本。您可以使用它来定义要调用 getter 或 setter.
的属性(实际上是成员变量)// LableTag is a class defined globally and GetAttribute() is a member
//template function
int i = Vox[1][2][3]->GetAttribute<LableTag>();
但是,我还没有看到它被用于定义 getters/setters。通常如果你想 "get something" 你只需要写一个具体的成员函数 GetSomething();