Возвращение константной ссылки на вектор объекта

У меня есть 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();