向量类私有/公共

Vectors Classes Private/Public

本文关键字:公共 向量      更新时间:2023-10-16

在c++中,最好将类的数据保存为私有成员。
如果一个类有一个vector作为成员,最好把它作为私有成员还是公共成员?

如果有一个vector作为私有成员,则不能方便地访问vector的成员函数。所以我必须为每个函数设计一个方法来访问向量方法?

例子:

class MyClass{
private:
     std::vector<int> _myints;
public:
     get_SizeMyints(){return _myints.size();}
     add_IntToMyints(int x){_myints.push_back(x));
};

还是最好保持vector为public并调用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();

};

现在我知道如何修改代码了

顺便说一句……一个问题,如果我需要在另一个类中复制向量,比如:GlBox。p_list = Snake。P_list(工程,如果是私有的)什么将是一个有效的方法,如果他们是私有的?
运行for循环来复制元素并将它们推回到GLBox中。p_list对我来说似乎有点效率低下(但可能只是一种印象):(

如果有人来清空向量或重新排列它的所有元素并不重要,那么将其公开。如果它很重要,那么是的,您应该将其设置为受保护/私有,并像您那样设置公共包装。【编辑】既然你说"这是一条蛇",那就意味着如果有人来取走或更换碎片,那就不好了。因此,你应该把它设为保护或隐私。(/编辑)

你可以简化它们中的很多:

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()函数将允许某人查看所有他们想要的向量,但不会让他们改变任何东西。然而,更好的做法是完全封装vector。这将允许您稍后用deque或list或其他东西替换vector。您可以使用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));
};

为了进行良好的封装,您应该将vector保持为私有。

你的问题不太具体,所以我本着同样的精神回答你:

一般来说,你的类应该被设计成表达一个特定的概念和功能。他们不应该只是传递另一个成员类。如果你发现自己复制了一个成员对象的所有接口函数,那就有问题了。

也许有时候你真的只是需要一些其他的东西。在这种情况下,考虑一个普通的旧聚合,甚至是一个元组。但是,如果您正在设计一个合适的类,请使接口对手头的任务有意义,并隐藏实现。这里的主要问题是,为什么要暴露向量本身?它在课堂上扮演什么角色?就类的语义而言,它的空性意味着什么?

找到合适的习惯用法和思想来为你的类设计一个最小的、模块化的接口,这个问题可能就会自己解决了。

还有一个想法:例如,如果您有一些基于范围的需求,请考虑公开一个接受一对迭代器的模板成员函数。

通常,良好的编码实践是将数据成员保持为私有或受保护,并提供访问它们所需的任何公共方法。并不是vector的所有方法(在这种情况下),而是对您的应用程序有用的方法。

这取决于你的类的目的。如果你只是想把vector包起来,想把它当作vector使用,可以提出一个将vector设为public的理由。

一般来说,我建议将其设置为私有,并提供一个适当的接口来操作容器。此外,如果一个不同的容器更合适,这允许您在底层更改容器(只要您不将公共接口绑定到容器类型)。

另外,避免以下划线开头的名称,因为有一些这样的标识符为实现保留,避免所有这些标识符比试图记住所有情况下的规则更安全。

需要认识到的一点是,当涉及到良好的封装时,使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
};

这在你的程序中提供了一个蛇对象的抽象,简化的接口给了你选择任何最适合它的实现的灵活性。如果出现这种情况,您总是可以在不破坏客户机代码的情况下更改该实现。

理论上,在面向对象编程中,任何属性都应该是私有的,并且可以通过Get()和Set()等公共方法访问它们。我认为你的问题是不完整的,但我从你想要实现的东西中理解到,你需要继承std::vector并扩展其功能,以满足你的快速访问需求,而不是混淆封装。(考虑先从任何c++书籍或其他OO语言中阅读"Inheritance")

话虽如此,您的代码可能如下所示:
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
}

希望这回答了你的问题