У меня есть класс, который должен в качестве входных данных использовать либо ссылку на внешние данные (без копирования), либо создавать сами данные на основе других входных данных. Я предпочитаю использовать ссылки (чтобы избежать разыменования, поскольку данные являются матрицами) и в итоге получилась следующая структура (упрощенно):
#include <iostream>
#include <vector>
using namespace std;
using VectI = vector<int>;
class A {
VectI x0;
VectI const & x = x0;
public:
A(VectI const & extX) : x(extX) {} // referencing existing external data
A(int i) { x0.push_back(i); x0.push_back(i*i); } // create from other data
void show_x()
{ cout << "x ="; for (auto&& i : x) cout << " " << i; cout << endl; }
};
int main() {
VectI myX = {1, 2, 3};
A a(myX); a.show_x(); // a references myX
A b(2); b.show_x(); // b creates its own data based on i=2
return 0;
}
Пример работает:
x = 1 2 3
x = 2 4
но есть ли потенциальные проблемы с этим подходом?
В частности, это тот факт, что я меняюсь x0
на что ссылается Const вектор x
«легальный» C ++, или на это могут пожаловаться другие компиляторы?
Кроме того, могу ли я быть уверен, что первый конструктор избегает копирования данных?
Это нормально в стандарте C ++ 11, но ваш код очень хрупкий.
В частности, сгенерированные компилятором конструкторы копирования и перемещения и оператор присваивания не будут работать правильно, поэтому вам придется создавать свои собственные.
Вы также можете столкнуться с висячими ссылками: помните, что продление времени жизни объекта из-за ссылки на const не транзитивно. Поведение при использовании A(VectI const & extX)
с анонимным временным не определено.
Используя указатель на VectI
— возможно, даже std::unique_ptr
к VectI
наряду с концепцией собственности может быть более безопасный путь.
Других решений пока нет …