создать новый вектор STL - PullRequest
4 голосов
/ 09 июня 2009

У меня есть ситуация, когда у меня есть указатель на вектор STL

так как

vector<MyType*>* myvector;

Мне нужно установить этот указатель на NULL в конструкторе и затем ленивую загрузку при касании свойства.

как я могу создать экземпляр для нового экземпляра вектора?

Ответы [ 5 ]

7 голосов
/ 09 июня 2009

Если вы правильно определили вектор:

vector<int>*   myvector;  // Note vector must be parametrized with a type.
                          // There is no such thing as a a naked vector.

Инициализировать в NULL

myclass::myclass()
   :myvector(NULL)       // You can use 0 here but I still like NULL because it
{}                       // gives me more information. Waiting for the new keyword.

Создание экземпляра при первом использовании:

myvectr = new vector<int>(100); // reserve some space as appropriate

Но вы не должны иметь указатель RAW в качестве члена вашего класса (если на то нет веских причин). Вам нужно будет написать свой собственный конструктор копирования и оператор присваивания.

Или же вы можете обернуть myvector умным указателем. Или даже лучше сделать его нормальным вектором. Нет реальной необходимости делать его указателем.

5 голосов
/ 09 июня 2009

Мне нужно установить этот указатель на NULL в конструкторе и затем ленивую загрузку при касании свойства.

Как я могу создать экземпляр для нового экземпляра вектора?

Я не уверен, что понимаю вас полностью. Почему бы просто не оставить вектор пустым и установить логическое значение, которое говорит, было ли загружено свойство или нет? В качестве альтернативы вы можете использовать boost::optional

boost::optional< vector<MyType*> > 

или

boost::optional< vector< shared_ptr<MyType> > >

Затем вы можете просто получить объект, разыменовав необязательный объект, и назначить ему вектор, как обычно.

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

Если вам действительно нужно использовать указатель, вы можете сделать это следующим образом

struct A {
    A():prop() { }
    ~A() { delete prop; }

    vector< MyType *>& get() { 
        if(!prop) prop = new vector< MyType* >();
        return prop;
    }

private:
    // disable copy and assignment. 
    A(A const&);
    A& operator=(A const&);
    vector< MyType* > *prop;

};

Или используйте shared_ptr, который будет подходить для моей программы (но boost :: option все равно будет первой опцией, после которой будет опция vector-and-boolean, после которой будет следующая)

struct A {
    typedef vector< shared_ptr<MyType> > vector_type;

    vector_type &get() { 
        if(!prop) { 
            prop.reset(new vector_type);
        }
        return *prop;
    }

private:
    // disable copy and assignment. 
    A(A const&);
    A& operator=(A const&);
    shared_ptr< vector_type > prop;         
};

Копирование и назначение отключены, так как они разделяют подпорку за сценой (мелкая копия), которая должна быть либо четко задокументирована, либо отключена путем глубокого копирования в этих функциях.

1 голос
/ 09 июня 2009

Вы не можете иметь указатель, подобный этому:

vector* myvector;

потому что вектор является классом шаблона и должен иметь тип. Вы могли бы сказать:

vector <int> * myvector = 0;

или

vector <string> * myvector = 0;

и затем динамически создать вектор:

myvector = new vector <string>;
1 голос
/ 09 июня 2009
myvector = new std::vector<yourtype>;
0 голосов
/ 09 июня 2009

Хорошо, чтобы инициализировать его, вам нужно будет по крайней мере установить его в NULL или экземпляр, подобный приведенному ниже, используя этот синтаксис. Также вы должны сделать это в том порядке, в котором поля объявлены, иначе могут произойти странные вещи.

// Field.
std::vector<int> *myvector;
// Constructor.
myclass() : myvector(new std::vector<int>) 
{ 
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...