Почему конфиденциальность зависит от класса, но константа не работает для объектов одного и того же класса? - PullRequest
0 голосов
/ 14 июля 2020

Я решил попробовать что-нибудь из любопытства, чтобы посмотреть, как это будет работать. Мне пришло в голову проверить, может ли один объект класса получить доступ к закрытым переменным другого объекта того же класса. По-видимому, может, если эта программа представляет собой какой-либо индикатор:

#include <iostream>

using namespace std;

class Colour
{
private:
    int var;
public:
    void setVar(int x)
    {
        var = x;
    }
    int getVar() const
    {
        return var;
    }
    int getOtherVar(Colour col) //steals the private var of another Colour object
    {
        return col.var;
    }
};

int main()
{
    Colour green;
    Colour red;

    green.setVar(54);
    red.setVar(32);

    cout << "Green is " << green.getVar() << endl;
    cout << "Red is " << red.getVar() << endl;
    cout << "Green thinks Red is " << green.getOtherVar(red) << endl;


    return 0;
}

Я ожидал, что она потерпит неудачу таким образом, чтобы каждый уникальный экземпляр класса имел доступ только к своему собственному частные члены. Я провел небольшое исследование и обнаружил, что конфиденциальность - это особенность класса c, а не особенность экземпляра c.

В любом случае, я решил поэкспериментировать и обнаружил что-то немного запутанное. Я отредактировал реализацию для getOtherVar() и превратил ее в следующую:

    int getOtherVar(Colour col) const
    {
        col.var = 67;
        return col.var;
    }

Я решил, что если объекты могут обращаться к членам друг друга, ключевое слово const не должно защищать другие объекты того же класса от тоже изменить? Это не так, и я понятия не имею, почему.

Ответы [ 3 ]

3 голосов
/ 14 июля 2020

const функция-член делает const только объектом, для которого вы вызываете эту функцию, то есть *this. А именно, «скрытый» параметр this этой функции-члена является указателем на константу. Но это не позволяет избежать изменения параметра col.

Чтобы сделать другой объект const, просто передайте его параметром const. В вашем случае вы, вероятно, захотите передать его по ссылке const:

int getOtherVar(const Colour& col) const
{
  col.var = 67;  // will not compile
  return col.var;
}

Передача по значению будет работать с копией аргумента функции.

Что касается доступа к каждому классу, если бы он был для каждого экземпляра, как бы вы реализовали конструкторы копирования / перемещения и операторы присваивания? Или другие функции, такие как бинарные операторы et c ...

3 голосов
/ 14 июля 2020

Текущее объявление getOtherVar просто гарантирует, что экземпляр, для которого вызывается метод, останется const. Если вы используете sh, чтобы добиться, чтобы col нельзя было изменить, вы хотите

int getOtherVar(const Colour& col) const
{
    col.var = 67;    // <== this will not be allowed
    return col.var;
}
1 голос
/ 14 июля 2020

Рассмотрим аргумент: когда вы разрабатываете класс, вы полностью контролируете его реализацию. Это означает, что нет особого смысла защищать члены других объектов этого класса от себя ... Противоположное верно для других классов, даже для производных: это то, что может разработать кто-то другой. Это причина для защиты членов ВАШЕГО класса от классов ДРУГИХ.

Что касается методов const, разница заключается в скрытом параметре this. В то время как у неконстантных методов этот параметр имеет тип Class*, у константных методов он имеет тип const Class*. Это правило не влияет на другие аргументы, которые могут быть изменены, даже если они принадлежат к одному классу.

...