【问题标题】:Copy private vectors between classes在类之间复制私有向量
【发布时间】:2011-08-31 09:58:32
【问题描述】:

如果是类的数据的向量,则应将其分配为该类的私有成员。 该类应提供访问所需向量方法的方法。

现在我有我的类 Snake,它为经典游戏封装了一条蛇。

typedef std::vector<Polygon4>::const_iterator const_iterator;
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;
    std::vector<Polygon4> p_list; //the vector
public:   

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

 //vector manipulation functions
 const_iterator p_list_begin() const {return p_list.begin();}
 const_iterator p_list_end() const {return p_list.end();}
 void add_IntToP_list(Polygon4 cube){p_list.push_back(cube);}
 void clear_list(){p_list.clear();}
 unsigned int get_list_size(){return p_list.size();}

};

我的程序中有另一个类,图形管理:

class MyGLBox{
private:
std::vector<Polygon4> p_list;
public:
     //do stuff...
     //management vectors:
     const_iterator p_list_begin() const {return p_list.begin();}
     const_iterator p_list_end() const {return p_list.end();}
     void add_IntToP_list(Polygon4 cube){p_list.push_back(cube););
     void clear_list(){p_list.clear();}
     unsigned int get_list_size(){return p_list.size();}
}

现在游戏中的每一帧我都需要将蛇 p_list 复制到 MyGLbox p_list 中。如果向量是公开的,那就很容易了:

myGLBox.p_list = snake.p_list;

现在如果他们是私人的:

transfer_function(*MyGLBox box, *Snake snake){
    const_iterator cube;
    for(cube = snake->p_list_begin(); cube != snake->p_list_end(); cube++){
         box->add_InTop_list(*cube);
    }
}

我想做的事对吗?有更好的方法吗?对我来说,for 循环似乎非常低效

【问题讨论】:

  • 你应该使用++cube而不是cube++

标签: c++ vector private


【解决方案1】:

如果你已经有一个函数

void add_IntToP_list(Polygon4 cube){p_list.push_back(cube););

对于添加单个元素,您可以添加另一个重载以添加一系列元素

void add_IntToP_list(vector<Polygon4>::const_iterator first, 
                      vector<Polygon4>::const_iterator last)
{ p_list.insert(p_list.end(), first, last); }

然后用你想添加的范围调用它,也许

box->add_IntToP_list(snake->p_list_begin(), snake->p_list_end());

【讨论】:

    【解决方案2】:

    您可以尝试使用好友功能:

    void transfer_function(MyGLBox * box, Snake * snake )
    {
        box->p_list = snake->p_list;
    }
    
    // in class MyGlBox
    friend void transfer_function(MyGLBox *, Snake *);
    
    // in class Snake
    friend void transfer_function(MyGLBox *, Snake *);
    

    但如果您有多个这样的场景,这很容易变得难以管理。

    或者,您仍然可以通过 get 成员直接公开向量。例如:

    // in class MyGLBox
    std::vector<Polygon4> & get_p_list( )
    {
        return p_list;
    }
    

    如果您返回向量本身,不一定总是“坏” - 因为无论如何您都会公开很多向量的功能,所以用户并没有获得对数据的不必要的控制权。

    【讨论】:

      【解决方案3】:

      很明显,友谊违反了编程练习。我认为您的方法是正确的,因为它提供了私有向量的访问器,我同意,复制所有数据效率低下。您可以做的一种优化是扩展向量:

      v.reserve(v.size() + distance(v_prime.begin(),v_prime.end()));
      v.insert(v.end(),v_prime.begin(),v_prime.end());
      

      我从here抢了密码。

      【讨论】:

        【解决方案4】:

        你有很多方法可以做到这一点。一种方法是 friend 您的其他函数,这样它就可以像访问公共变量一样访问您的 vector

        另一个是让变量本身public。有些人可能会争辩说这不是好的做法等,但这很荒谬。您是否试图“保护”vector 免受自己的侵害?!这就是你对自己编程的信心吗?对我来说,private 仅适用于您编写库供他人使用而不是在您自己的程序中使用的情况。

        最后,对你所说的话发表评论。您提出的for 循环一点也不低效。它比使用= 效率低,是的,但逐个添加也没有那么糟糕。 vector 的摊销业绩是O(1)。事实上,如果插入某些东西的成本是1,那么添加向量就会摊销成本2

        【讨论】:

        • 我想让项目开源,我希望其他程序员(如果有的话)能够使用/理解我所做的。但无论如何还是要回答:D
        • 我仍然建议提供良好的文档,而不是将其设为私有。但是,如果您坚持,我建议使用friend。您不需要为整个其他班级加好友,您可以使用 friend class::function; 以便仅加好友该特定功能。
        猜你喜欢
        • 2011-08-22
        • 2011-11-06
        • 2020-10-03
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-10-31
        • 2015-05-04
        相关资源
        最近更新 更多