Возвращение константной ссылки на вектор объекта
У меня есть 2 вопроса, связанные с одной и той же проблемой:
-
Как вернуть ссылку на вектор, принадлежащий классу?
У меня есть этот класс:
class sys{
protected:
vector<int> s;
public:
sys();
vector<int>& getS() {return s;} //(1)
};
(1) должен вернуть ссылку вектора s
. Однако в main()
:
main(){
sys* my_sys = new sys();
vector<int> &t1 = my_sys->getS(); //(2)
vector<int> t2 = my_sys->getS(); //(3)
...
}
-
t1
является ссылкой на s
(т.е. при изменении t1
my_sys.s
).
-
t2
- COPY s
(т.е. при изменении t2
my_sys.s не изменяется).
Почему работает строка (3)?
-
Я не хочу, чтобы было возможно изменить my_sys.s
вне класса, но я хочу вернуть ссылку из-за эффективности. Где я могу поставить const
?
Я попытался изменить строку (1) на
const vector<int>& getS() {return s;} //(4)
но я не уверен, что этого достаточно.
Ответы
Ответ 1
Строка 3 работает, потому что t2 копируется из ссылки, возвращаемой getS()
То, как вы const-квалифицируете ссылку, возвращаемую getS(), в порядке. Вы также можете const-qualify getS(), то есть:
const vector<int>& getS()const;
так что getS() можно было бы вызвать в const sys.
Ответ 2
Строка 3 работает, потому что С++ вызывает конструктор копирования на векторе.
Ваша функция возвращает ссылку, эта ссылка передается конструктору векторной копии, а ваша переменная t2 построена.
Это разрешено, поскольку конструктор копирования вектора не определен как явный.
Вы не можете защититься от этого с помощью общего типа.
В своем классе вы можете выделить конструктор копирования явным, и присваивание не получится.
Вместо этого вы можете вернуть указатель const.
Это защитит от копирования - но может быть опасно, поскольку пользователи могут ожидать, что они смогут передать указатель за пределы допустимой области.
const vector<int>* getS() {return &s;} //(4)
Ответ 3
Линия (3)
Для типа int тривиально копировать. Если вы разместите объекты там, и у них есть Copy CTor, это также сработает.
Линия (4)
Сделать это
const vector<int>& getS() const {return s;}
поэтому функция также объявляется как const.
И назовите это так
const vector<int> & t1 = my_sys->getS();