Копировать частные векторы между классами - PullRequest
2 голосов
/ 31 августа 2011

Векторы if, являющиеся данными класса, должны быть назначены как закрытые члены этого класса.Класс должен предоставлять методы для доступа к необходимым векторным методам.

Теперь у меня есть класс 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);
    }
}

это правильно, что я пытаюсь сделать?Есть ли лучший способ сделать это?Мне цикл кажется довольно неэффективным

Ответы [ 4 ]

0 голосов
/ 31 августа 2011

Если у вас уже есть функция

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());
0 голосов
/ 31 августа 2011

Кажется довольно ясным, что дружба нарушает упражнение по программированию.Я думаю, что ваш метод верен в том смысле, что он обеспечивает доступ к частному вектору, и я согласен, что неэффективно копировать все эти данные.Одна оптимизация, которую вы можете сделать, - это расширить вектор:

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

Я ограбил код от здесь .

0 голосов
/ 31 августа 2011

У вас есть много способов сделать это.Один способ - это friend другие ваши функции, чтобы он мог обращаться к вашему vector как к публичной переменной.

Другой - сделать саму переменную public.Некоторые могут утверждать, что это не очень хорошая практика и т. Д., Но это смешно.Вы пытаетесь "защитить" vector от себя ?!Это насколько вы уверены в своем собственном программировании?Для меня создание private хорошо только тогда, когда вы пишете библиотеку, которую другие могут использовать не в вашей собственной программе.

И, наконец, замечание о том, что вы сказали.Представленный вами цикл for вовсе не является неэффективным.Это на менее эффективно, чем использование =, правда, но добавление по одному также не так уж и плохо.vector амортизированная производительность O(1).Фактически, если вставка чего-либо должна была стоить 1, добавление в вектор амортизировало стоимость 2.

0 голосов
/ 31 августа 2011

Вы можете попробовать использовать функцию друга:

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

Но если у вас есть несколько таких сценариев, это может легко стать неуправляемым.

В качестве альтернативы, вы все равно можете выставить вектор напрямую черезполучить член.Например:

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

Это не всегда «плохо», если вы возвращаете сам вектор - так как вы все равно предоставляете большую часть функциональности вектора, это не значит, что пользователь получил нежелательный контроль над данными.

...