矢量类私人/公共

时间:2011-08-29 21:09:18

标签: c++ class vector private public

在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中似乎对我来说有点无效(但可能只是一个印象):(

7 个答案:

答案 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
}

希望这能回答你的问题