2017-02-09 17 views
1

Я хочу переопределить [] оператор для вектора. Я думал, что самый простой способ для достижения этой цели является создать свой собственный класс, что-то вроде этого (это упрощена пример):Сохранение ссылки внутри класса

class MyVec 
{ 
private: 
    std::vector<double> x; // I don't need a copy in here, it could be a reference 
public: 
    MyVec(const std::vector<double>& y) { x = y; } 
    double operator[](int i) { return x[i-1]; } 
}; 

Теперь проблема заключается в том, что я в принципе не нужно копировать данные x, я мог бы хранить ссылку на него, но, насколько я знаю, я не могу использовать неинициализированные ссылки в классе. Тем не менее, может быть, есть какое-то обходное решение для этого, чтобы работать без копирования данных?

+0

Что относительно наследства? – zapredelom

+0

Что значит «классное строительство не допускает этого»? – Quentin

+0

«классное строительство не позволяет этого» - это требование невозможности того, что вы хотите, чтобы читатели могли реализовать для вас. –

ответ

2

Для ввода конструктора, такого как MyVec(const std::vector<double>& y) { x = y; }, элемент x будет сконфигурирован по умолчанию и затем назначен y в корпусе конструктора. Но ссылочные элементы не могут быть построены по умолчанию.

Так что если вы объявляете элемент в качестве ссылки вы должны инициализировать их member initializer list:

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

например.

class MyVec 
{ 
private: 
    const std::vector<double>& x; // it's a reference (to const) 
public: 
    MyVec(const std::vector<double>& y) : x(y) {} 
    double operator[](int i) { return x[i-1]; } 
}; 

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

+0

Оба ответа велики, но этот появился несколько секунд назад, поэтому я принимаю это. Спасибо вам обоим! – Tim

3

конструкция класса не позволяет этого

Это делает, вам просто нужно использовать member initializer list. С его помощью рекомендуется использовать способ инициализации членов class от конструктора - вы не должны использовать для этого тело конструктора.

class MyVec 
{ 
private: 
    const std::vector<double>& x; 
public: 
    MyVec(const std::vector<double>& y) : x{y} { } 
    double operator[](int i) { return x[i-1]; } 
}; 

wandbox example


Обратите внимание, что если вы берете const& в конструкторе, вам нужно хранить const&, в противном случае вы потеряете const -ness пройденных аргумента конструктора.

+0

Это немного опасно, так как внешний вектор может быть уничтожен до объекта MyVec. Есть идеи? –

+0

@MartinZhai: вы не можете много сделать - будьте осторожны и документируйте семантику 'MyVec'. C++ не имеет способа защитить пользователя от этой ситуации ... Rust's * loan checker * является одной из точек продажи языка и генерирует ошибку времени компиляции в случае описанной вами ситуации. –

+0

@MartinZhai: C++ не поддерживает ограниченное владение, но Rust делает. Для этого нужна языковая поддержка. Руста обеспечивает его. –