在C ++中,最好将类的数据保存为私有成员 如果一个类有一个向量作为成员,最好把它作为私人或公共成员吗?
如果我有一个向量作为私有成员,我无法轻松访问向量的成员函数。所以我必须为我需要访问向量方法的每个函数设计一个类吗?
给出的例子:
class MyClass{
private:
std::vector<int> _myints;
public:
get_SizeMyints(){return _myints.size();}
add_IntToMyints(int x){_myints.push_back(x));
};
或者更好地保持向量公开并调用MyClass._myints.push_back(x)?
---------------------编辑--------------
并且只是为了明确这个问题需要什么:
snake.h:
enum directions{UP, DOWN, RIGHT, LEFT, IN, OUT, FW, RW };
class Snake
{
private:
enum directions head_dir;
int cubes_taken;
float score;
struct_color snake_color;
V4 head_pos;
public:
std::vector<Polygon4> p_list; //the public vector which should be private...
Snake();
V4 get_head_pos();
Polygon4 create_cube(V4 point);
void initialize_snake();
void move(directions);
void set_head_dir(directions dir);
directions get_head_dir();
void sum_cubes_taken(int x);
int get_cube_taken();
void sum_score(float x);
float get_score();
void set_snake_color();
};
现在我知道如何更改代码。
btw ...一个问题,如果我需要在另一个类中复制这样的向量:GlBox.p_list = Snake.p_list(如果是私有的话),如果它们是私有的,那将是一个有效的方法? /> 运行一个for循环来复制元素并将它们放回GLBox.p_list中似乎对我来说有点无效(但可能只是一个印象):(
答案 0 :(得分:4)
如果有人出现并清空向量或重新排列其所有元素并不重要,那么将其公之于众。如果它很重要,那么是的,你应该让它保护/私有,并像你一样制作公共包装。 [编辑]因为你说“它是一条蛇”,这意味着如果有人来取消或更换位,那就不好了。因此,您应该将其保护或保密。 [/编辑]
你可以简化很多:
MyClass {
private:
std::vector<int> _myints;
public:
const std::vector<int>& get_ints() const {return _myints;}
add_IntToMyints(int x){_myints.push_back(x));
};
get_ints()
函数允许某人查看所有他们想要的向量,但不会让他们改变任何东西。但是,更好的做法是完全封装矢量。这将允许您稍后使用双端队列或列表或其他内容替换向量。您可以使用std::distance(myobj.ints_begin(), myobj.ints_end());
MyClass {
private:
std::vector<int> _myints;
public:
typedef std::vector<int>::const_iterator const_iterator;
const_iterator ints_begin() const {return _myints.begin();}
const_iterator ints_end() const {return _myints.end();}
add_IntToMyints(int x){_myints.push_back(x));
};
答案 1 :(得分:2)
为了获得良好的封装效果,您应该将矢量保密。
答案 2 :(得分:2)
你的问题不是很具体,所以这是一个同样精神的答案:
通常,您的课程应设计为表达特定的概念和功能。他们不应该只是通过另一个成员班。如果你发现自己复制了成员对象的所有接口函数,那就错了。
有时候你真的只需要收集其他东西。在这种情况下,考虑一个普通的旧聚合,甚至是一个元组。但是如果你正在设计一个合适的类,那么使界面对手头的任务有意义,并隐藏实现。所以这里的主要问题是,为什么需要公开矢量本身?它在课堂上的作用是什么?它的空虚在你班级的语义方面意味着什么呢?
找到合适的习语和想法,为你的班级设计一个最小的模块化界面,这个问题可能会自行消失。
(还有一个想法:例如,如果您有一些基于范围的需求,请考虑公开接受一对迭代器的模板成员函数。这样,您可以利用通用算法的强大功能,而不依赖于容器的选择。)< / p>
答案 3 :(得分:0)
通常,良好的编码实践是保护您的数据成员的私有或受保护,并提供访问它们所需的任何公共方法。并非所有(在这种情况下)矢量的方法,只是对您的应用程序有用的方法。
答案 4 :(得分:0)
这取决于你班级的目的。如果您只是尝试包装矢量并希望将其用作矢量,则可以创建一个参数以使该矢量公开。
一般来说,我建议将其设为私有,并提供适当的界面来操纵容器。此外,如果不同的容器更合适(只要您不将公共接口绑定到容器类型),就可以更改引擎盖下的容器。
另外,请避免使用以下划线开头的名称,因为有一些此类标识符保留用于实现,并且更安全的是避免所有这些,而不是在所有情况下都记住规则。
答案 5 :(得分:0)
需要注意的一点是,在良好的封装方面,使std::vector
私有只是故事的一半。例如,如果您有:
class MyClass {
public:
// Constructors, other member functions, etc.
int getIntAt(int index) const;
private:
std::vector<int> myInts_;
};
...然后可以说,这并不仅仅是让myInts_
公开。无论哪种方式,客户端都将使用MyClass
编写代码,这取决于底层表示需要使用std::vector
的事实。这意味着将来,如果您认为更有效的实施将改为使用std::list
:
class MyClass {
public:
// Constructors, other member functions, etc.
int getIntAt(int index) const; // whoops!
private:
std::list<int> myInts_;
};
...现在你遇到了问题。由于您无法通过索引访问std::list
,因此您必须摆脱getIntAt
,或使用循环实现getIntAt
。这两种选择都不好;在第一种情况下,您现在拥有代码无法编译的客户端。在第二种情况下,您现在拥有的代码只有静默的效率降低。
这是暴露任何特定于您选择的实施的公共成员函数的危险。在设计类接口时,必须牢记灵活性/未来的维护。您可以通过多种方式对您的特定示例执行此操作;看看Mooing Duck对一个暴露迭代器的接口的回答。
或者,如果您希望最大限度地提高代码可读性,可以围绕MyClass
逻辑表示的界面设计界面;在你的情况下,一条蛇:
class MyClass {
public:
// Constructors, etc.
void addToHead(int value);
void addToTail(int value);
void removeFromHead();
void removeFromTail();
private:
// implementation details which the client shouldn't care about
};
这提供了程序中蛇对象的抽象,简化的界面使您可以灵活地选择最适合的实现。如果出现这种情况,您可以随时更改该实现,而不会破坏客户端代码。
答案 6 :(得分:-1)
理论上,在面向对象编程中,任何属性都应该是私有的,并通过公共方法(如Get()和Set())获取对它们的访问权限。 我认为你的问题并不完整,但我从你想要实现的目标中理解你需要继承std :: vector并扩展其功能,以满足你的快速访问需求而不是搞乱封装。 (考虑首先从任何C ++书籍或其他OO语言阅读“继承”)
话虽如此,您的代码可能如下所示:
class MyClass : public std::vector<int>
{
//whatever else you need goes here
}
int main(void)
{
MyClass var;
var.push_back(3);
int size = var.size(); // size will be 1
}
希望这能回答你的问题