简体   繁体   中英

Is there a function that help using a private struct

I need a function that can enter a private struct

    #include <iostream>
    using namespace std;

    struct abc {
    private:
        int a;
    }b;

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

This will break the encapsulation.

If you need to read the variable a you create a getter:

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

if you need to modify the variable you should create a setter:

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

There is a way use friend function but I don't advice you to do this.

If it is a struct consider making a public if you need access and no encapsulation.

If you want to allow a specific class/struct or function to access private member, use the friend declaration. This is normally only used for closely related things, so as to not make the members accessible to everything elsewhere (in other languages, things like internal are similar).

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");
}

Frequently if you want read-only access, a "getter" will be used, eg

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

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

And for read-write a get and set function. The set function may do extra validation, or other logic.

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
}

The private fields and methods should not be accessed by anyone but the class that declares them. However there are situations where it is needed. For example if you wanted to serialize/print your struct. For these cases you can declare a function or another class with a friend keyword. So for example:

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

    int a;
};

You would then implement the function with the same signature std::ostream &operator<<(std::ostream &stream, const abc &s); somewhere and it would have access to abc::a :

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

This would allow using your struct for example with std::cout .

Note that there are not many genuine cases like this one and you should avoid using friend as much as possible. In this case for example a getter method would do the same thing and you would avoid the whole problem without breaking encapsulation.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM