向量类私有/公共

发布于 2024-12-01 21:23:36 字数 1336 浏览 2 评论 0原文

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



};

现在我知道如何更改代码了。

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

In C++ is always better to keep data of a class as private members.
If a class has a vector as member is better to put it as a private or public member?

If I have a vector as private member I cannot easily access to the member function of the vector. So I have to design the class with a method for every function I need to access the vector methods?

Example given:

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

or is better to keep the vector public and call MyClass._myints.push_back(x)?

---------------------edit--------------

and just for clarity for what is needed this question:

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



};

so now I know how to change the code.

btw... a question, if I need to copy the vector in an other class like this: GlBox.p_list = Snake.p_list (works if are private) what will be an efficent method if they where private?
Running a for cycle to copy the the elements and pusshing back them in the GLBox.p_list seems a bit inefficent to me (but may be just an impression) :(

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

忆悲凉 2024-12-08 21:23:36

如果有人清空向量或重新排列它的所有元素并不重要,那么将其公开。如果它很重要,那么是的,您应该将其设置为受保护/私有,并像您一样制作公共包装器。 [编辑] 既然你说“它是一条蛇”,那就意味着如果有人来移除或更换碎片,那就不好了。因此,您应该将其设置为受保护或私有。 [/Edit]

您可以简化其中的许多内容:

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

If it doesn't matter if someone comes along and empties the vector or rearranges all it's elements, then make it public. If it matters, then yes, you should make it protected/private, and make public wrappers like you have. [Edit] Since you say "it's a snake", that means it'd be bad if someone came and removed or replaced bits. Ergo, you should make it protected or private. [/Edit]

You can simplify a lot of them:

MyClass {
private:
     std::vector<int> _myints;
public:
     const std::vector<int>& get_ints() const {return _myints;}
     add_IntToMyints(int x){_myints.push_back(x));
};

That get_ints() function will allow someone to look at the vector all they want, but won't let them change anything. However, better practice is to encapsulate the vector entirely. This will allow you to replace the vector with a deque or list or something else later on. You can get the size with 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));
};
谁把谁当真 2024-12-08 21:23:36

为了获得良好的封装,您应该将向量保持私有。

For good encapsulation, you should keep your vector private.

寂寞清仓 2024-12-08 21:23:36

您的问题不是很具体,因此本着同样的精神给出了答案:

通常,您的类应该设计为表达特定的概念和功能。他们不应该仅仅传递另一个成员类别。如果您发现自己复制了成员对象的所有接口函数,则说明有问题。

也许有时你真的只需要收集其他东西。在这种情况下,请考虑一个普通的旧聚合,甚至一个元组。但是,如果您正在设计一个合适的类,请使接口对手头的任务有意义,并隐藏实现。所以这里的主要问题是,为什么需要公开向量本身?它在班级中的作用是什么?就你的类的语义而言,它的空性意味着什么?

找到合适的习惯用法和想法来为你的班级设计一个最小的模块化界面,这个问题可能会自行消失。

(还有一个想法:如果您有一些基于范围的需求,请考虑公开一个接受一对迭代器的模板成员函数。这样您就可以利用通用算法的强大功能,而无需依赖于容器的选择。)

Your question is not very concrete, so here's an answer in the same spirit:

Generally, your classes should be designed to express a particular concept and functionality. They should not just hand through another member class. If you find yourself replicating all the interface functions of a member object, something is wrong.

Maybe sometimes you really just need a collection of other things. In that case, consider a plain old aggregate, or even a tuple. But if you're designing a proper class, make the interface meaningful to the task at hand, and hide the implementation. So the main question here is, why do you need to expose the vector itself? What is its role in the class? What does its emptiness signify in terms of the semantics of your class?

Find the appropriate idioms and ideas to design a minimal, modular interface for your class, and the question might just go away by itself.

(One more idea: If for example you have some range-based needs, consider exposing a template member function accepting a pair of iterators. That way you leverage the power of generic algorithms without depending on the choice of container.)

蓬勃野心 2024-12-08 21:23:36

通常,良好的编码实践是保持数据成员私有或受到保护,并提供访问它们所需的任何公共方法。并不是(在本例中)向量的所有方法,只是对您的应用程序有用的方法。

Normally, good coding practice is to keep your data members private or protected, and provide whatever public methods will be needed to access them. Not all the methods of (in this case) vector, just what will be useful for your application.

二智少女 2024-12-08 21:23:36

这取决于您班级的目的。如果您只是尝试包装向量并希望将其用作向量,您可以提出将向量公开的论点。

一般来说,我建议将其设为私有并提供适当的接口来操作容器。此外,如果不同的容器更合适(只要您不将公共接口与容器类型绑定),您就可以在后台更改容器。

此外,请避免使用以下划线开头的名称,因为有一些此类标识符是为实现保留的,并且避免所有这些标识符比尝试记住所有情况下的规则更安全。

That depends on your class's purpose. If you're trying simply trying to wrap the vector and want to use it as a vector you could make an argument for making the vector public.

Generally speaking I would suggest making it private and providing an appropriate interface to manipulate the container. Additionally this lets you change the container under the hood if a different container would ever be more appropriate (as long as you don't tie your public interface to the container type).

Further as an aside, avoid names that begin with underscores as there are some such identifiers reserved for the implementation and it's safer to just avoid all of them rather than trying to remember the rules in all cases.

高跟鞋的旋律 2024-12-08 21:23:36

需要认识到的一点是,就良好的封装而言,将 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
};

这在您的程序中提供了蛇对象的抽象,并且简化的接口使您可以灵活地选择最适合它的实现。如果出现这种情况,您可以随时更改该实现,而不会破坏客户端代码。

A point to realize is that making the std::vector private is only half of the story when it comes to good encapsulation. For example, if you have:

class MyClass {
    public:
        // Constructors, other member functions, etc.

        int getIntAt(int index) const;

    private:
        std::vector<int> myInts_;
};

...then arguably, this is no better than just making myInts_ public. Either way, clients will write code using MyClass which is dependent on the fact that the underlying representation requires the use of a std::vector. This means that in the future, if you decide that a more efficient implementation would utilize a std::list instead:

class MyClass {
    public:
        // Constructors, other member functions, etc.

        int getIntAt(int index) const; // whoops!

    private:
        std::list<int> myInts_;
};

...now you have a problem. Since you can't access into a std::list by index, you would either have to get rid of getIntAt, or implement getIntAt using a loop. Neither option is good; in the first case, you now have clients with code that doesn't compile. In the second case, you now have clients with code that just silently became less efficient.

This is the danger of exposing any public member functions which are specific to your choice of implementation. It's important to keep flexibility/future maintenance in mind when designing your class interface. There are a number of ways you could do this with your particular example; see Mooing Duck's answer for one such interface that exposes iterators.

Or, if you would like to maximize code readability, you could design the interface around what MyClass logically represents; in your case, a snake:

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

This offers an abstraction of a snake object in your program, and the simplified interface gives you the flexibility to choose whatever implementation suits it best. And if the situation arises, you can always change that implementation without breaking client code.

晨曦慕雪 2024-12-08 21:23:36

理论上,在面向对象编程中,任何属性都应该是私有的,并通过公共方法(例如 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
}

希望这能回答您的问题

Theoretically in Object Oriented Programming any attributes should be private and gain access to them via public methods such as Get() and Set().
I think you question is not complete, but what I understand from what you're trying to achieve you need to inherit from std::vector and extend its functionality, to both satisfy your fast access needs and not messing around with encapsulation. (Consider reading on "Inheritance" first from any C++ book, or other OO language)

Having said that, your code might look as following:

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
}

Hope this answered your question

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文