2015-09-23 2 views
0

В C++ у меня есть класс MyClass, который во время построения ссылается на int, чтобы создать внутреннюю ссылку на него.Ссылки на элементы в векторах во время строительства

У меня тогда есть класс BigClass, содержащий как std::vector<int> vecInt_, так и std::vector<MyClass> vecMyClass_. Конструктор BigClass принимает в качестве аргумента размер векторов vecInt_ и vecMyClass_. В конструкторе BigClass я хотел бы, чтобы каждый элемент vecMyClass_ использовал в своем конструкторе соответствующий элемент vecInt_.

Как я могу это написать? Если бы я мог вызвать конструкторы vecMyClass из тела конструктора BigClass, который будет выглядеть так:

BigClass(int nbElem) : 
    vecInt_(nbElem), 
    vecMyClass_(nbElem) 
{ 
    for (int i = 0; i < nbElem; ++i) 
    { 
     vecMyClass_[i](vecMyInt_[i]); 
    } 
} 

Но, конечно, скобка здесь будет означать operator(), а не конструктор. Я не могу написать что-то вроде:

vecMyClass_[i] = MyClass(vecMyInt_[i]); 

Поскольку MyClass содержит ссылку, а не указатель, и, таким образом, эталонное значение не может быть изменено.

+0

Do 'vecInt_' и' vecMyClass_' должны быть 'const'? –

+0

Элементы вектора не будут добавлены/удалены, однако значения, сохраненные в векторе, будут изменены. – vkubicki

ответ

1

Вы можете инициализировать vecMyClass_ как пустой вектор и emplace_back элементов в ней, а вы строите им:

BigClass(int nbElem) : 
    vecInt_(nbElem), 
    vecMyClass_() //empty vector 
{ 
    vecMyClass_.reserve(nbElem); //avoid reallocations 
    for (int i = 0; i < nbElem; ++i) 
    { 
     vecMyClass_.emplace_back(vecInt_[i]); 
    } 
} 
0
#include <vector> 
#include <iostream> 

struct MyClass { 
    int& x; 
    MyClass(int& x) : x(x) {} 
}; 

struct BigClass { 
    BigClass(std::size_t nb_elems) : ints(nb_elems) { 
    my_classes.reserve(nb_elems); 
    for(int& x : ints) { 
     my_classes.emplace_back(x); 
    } 
    } 

    std::vector<int> ints; 
    std::vector<MyClass> my_classes; 
}; 

int main() 
{ 
    BigClass b{10}; 
    for(int& x : b.ints) { 
    x = 23; 
    } 

    // they are all 23 
    for(auto& c : b.my_classes) { 
    std::cout << c.x << std::endl; 
    // change them 
    c.x = 24; 
    } 

    // they are all 24 now 
    for(auto& c : b.ints) { 
    std::cout << c << std::endl; 
    } 
    return 0; 
} 
1

Это не звучит как очень хорошая идея. В какой-то момент добавление элементов в vecMyInt_ приведет к расширению вектора, т. Е. Распределению новой памяти и перемещению элементов там, и освобождению старой памяти. Это означает, что ссылки, хранящиеся в экземплярах MyClass, будут недействительными.

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