1

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");
    }
Marcelluxx
  • 23
  • 5
  • 13
    What's the point of it being private if you want to access it?! – DeiDei Apr 11 '19 at 13:22
  • I agree, what's the point. But if you want to access the `a` vairable then the only ways are with a method of `abc` or with a function declared as a friend of `abc`. You will get a much better answer if you explain **why** you want to do this. – john Apr 11 '19 at 13:25
  • `struct a { int a; }` and then `((a*)&b)->a = 42` should do it. – DeiDei Apr 11 '19 at 13:27
  • 2
    @DeiDei that would be undefined behaviour - casting objects to be things they're not might look like it works, but even if they have the same members the compiler may have optimised them differently. Better would be to have `struct a{int a;}; struct abc: private a{};` (also - answers are below so that people can down vote them) – UKMonkey Apr 11 '19 at 13:31
  • Do you have access to `abc` definition ? – cprogrammer Apr 11 '19 at 13:34
  • @DeiDei why not `struct a { int a; }` and then `b.a = 42;` ? :P – 463035818_is_not_an_ai Apr 11 '19 at 13:34
  • About [using namespace std](https://stackoverflow.com/questions/1452721/why-is-using-namespace-std-considered-bad-practice) – Aconcagua Apr 11 '19 at 13:52
  • Off-topic: It's not the task of a console application to keep a console window open, so you shouldn't do stuff like `system("pause")`, `getchar` or `std::cin >> ...`. All you achieve this way is that your programme won't be usable in scripts (there's no-one to hit any key). Instead, just open a console window manually (cmd.exe) and start your programme from within. – Aconcagua Apr 11 '19 at 13:55

3 Answers3

4

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.

Petar Velev
  • 2,305
  • 12
  • 24
1

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, e.g.

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
}
Fire Lancer
  • 29,364
  • 31
  • 116
  • 182
0

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.

Resurrection
  • 3,916
  • 2
  • 34
  • 56