开发者

Copy private vectors between classes

Vectors if are data of a class should be assigned as private member of that class. The class should provide the methods to access the vector methods needed.

Now I have my class Snake which encapsulate a snake for the classic game.

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

};

I have an other class in my program, the graphic management:

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

Now every frame in the game I need to copy the snake p_list into the MyGLbox p_list. If the vectors were public it would have been pretty easy:

myGLBox.p_list = snake.p_list;

now if they are private:

transfer_function(*MyGLBox box, *Snake snake){
    const_it开发者_高级运维erator cube;
    for(cube = snake->p_list_begin(); cube != snake->p_list_end(); cube++){
         box->add_InTop_list(*cube);
    }
}

is it right what I'm trying to do? Is there a better way to do it? To me the for cycle seems pretty inefficent


If you already have a function

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

for adding a single element, you can add another overload for adding a range of elements

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

and then call that with the range you want to add, maybe

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


You could try using a friend function:

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

But if you have multiple such scenarios, this can easily become unmanageable.

Alternatively, you could still expose the vector directly via a get member. E.g:

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

It's not necessarily always "bad" if you return the vector itself - since you expose a lot of the vector's functionality anyways, it's not like the user has been given unwanted control over the data.


It seems pretty clear that friendship violates the programming exercise. I think your method is correct in that it provides the accessors to the private vector, and I agree, it is inefficient copying all that data. One optimisation you can do is to extend the vector:

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

I robbed the code from here.


You have many ways to do it. One way is to friend your other functions so it can access your vector like a public variable.

Another is to make the variable itself public. Some may argue it's not good practice etc, but that's ridiculous. Are you trying to "protect" the vector from yourself?! Is that how confident you are in your own programming? To me, making private is only good for when you are writing a library for others to use not in your own program.

And finally, a remark on what you said. The for loop you presented is not at all inefficient. It is less efficient than using =, true, but adding one by one is also not that bad. vector's amortized performance is O(1). In fact if inserting something was intended to have cost 1, adding in vector has amortized cost 2.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜