Есть ли функция, которая помогает использовать частную структуру - PullRequest
1 голос
/ 11 апреля 2019

Мне нужна функция, которая может вводить приватную структуру

    #include <iostream>
    using namespace std;

    struct abc {
    private:
        int a;
    }b;

    int main(){
        //i want to use the variable a
        system("pause");
    }

Ответы [ 3 ]

4 голосов
/ 11 апреля 2019

Это нарушит инкапсуляцию.

Если вам нужно прочитать переменную a, вы создаете геттер:

struct abc {
int getA() const;
private:
    int a;
};

, если вам нужно изменить переменную, вы должны создать сеттер:

struct abc {
void setA(int);
private:
    int a;
};

Существует способ использования friend function , но я не советую вам делать это.

Если это struct, рассмотрите возможность сделать a публичным, если вам нужнодоступ и отсутствие инкапсуляции.

1 голос
/ 11 апреля 2019

Если вы хотите разрешить определенному классу / структуре или функции доступ к закрытому члену, используйте объявление friend. Обычно это используется только для тесно связанных вещей, чтобы не делать членов доступными для всего остального (на других языках такие вещи, как internal похожи).

struct abc {
private:
    int a;
    friend int main();
};

void foo(abc &x) {
    x.a = 5; // ERROR
}
int main(){
    abc x;
    x.a = 2; // OK
    foo(x);
    //i want to use the variable a
    system("pause");
}

Часто, если вы хотите доступ только для чтения, будет использоваться «получатель», например,

struct abc {
    int get_a()const { return a; }
private:
    int a = 45;
};

int main() {
    abc x;
    std::cout << x.get_a(); // OK
}

И для чтения-записи функции get и set. Функция set может выполнять дополнительную проверку или другую логику.

struct abc {
    int get_a()const { return a; }
    void set_a(int x)
    {
        if (x % 2) throw std::invalid_argument("abc must be even");
        a = x;
    }
private:
    int a = 45;
};

int main() {
    abc x;
    x.set_a(50);
    std::cout << x.get_a();
    x.set_a(51); // throws
}
0 голосов
/ 11 апреля 2019

Закрытые поля и методы не должны быть доступны никому, кроме класса, который их объявляет. Однако бывают ситуации, когда это необходимо. Например, если вы хотите сериализовать / распечатать структуру. В этих случаях вы можете объявить функцию или другой класс с ключевым словом friend. Так, например:

struct abc
{
private:
    friend std::ostream &operator<<(std::ostream &stream, const abc &s);

    int a;
};

Затем вы реализуете функцию с такой же сигнатурой std::ostream &operator<<(std::ostream &stream, const abc &s); где-нибудь, и у нее будет доступ к abc::a:

std::ostream &operator<<(std::ostream &stream, const abc &s)
{
    return stream << s.a;
}

Это позволит использовать вашу структуру, например, с std::cout.

Обратите внимание, что не так много подлинных случаев, подобных этому, и вам следует избегать максимально возможного использования friend. В этом случае, например, метод get будет делать то же самое, и вы избежите всей проблемы, не нарушая инкапсуляцию.

...