2

I have this class declared. I observed that in the method distance(Point b), how is it possible to access the private members of Point - b.x and b.y? If I try to access b.x and b.y in main, it is not allowed.

#include <iostream>
#include <cmath>

using namespace std;

class Point {
private:
    int x, y;
public:
    Point() {
        cout << "Constructor called" << endl;
        x = 0; y = 0;
    }

    ~Point() {
    }

    void set(int a, int b) {
        x = a;
        y = b;
    }

    void offset(int dx, int dy) {
        x += dx;
        y += dy;
    }

    void print() {
        cout << "(" << x << "," << y << ")" << endl;
    }

    // HERE
    double distance(Point b) {
        return (sqrt(pow(x-b.x, 2)+pow(y-b.y, 2)));
    }
};

int main() {
Point p, q;

p.print();
p.offset(4, 3);
p.print();

q.set(10, 2);

cout << "Distance: " << p.distance(q) << endl;

return 0;
}

NOTE: I have compiled and ran the program on ideone.com

aakash
  • 751
  • 5
  • 18
  • 1
    Because `distance` is a member of `Point`. – chris Apr 01 '13 at 06:12
  • If class member functions couldn't access private variables, what could? – David Schwartz Apr 01 '13 at 06:14
  • possible duplicate of [What are access specifiers? Should I inherit with private, protected or public?](http://stackoverflow.com/questions/5447498/what-are-access-specifiers-should-i-inherit-with-private-protected-or-public) – Alok Save Apr 01 '13 at 06:14
  • I am just confused / did not know that even 'other' objects can do that!! – aakash Apr 01 '13 at 06:15
  • 1
    @aakash: While it doesn't work this way in every language, for C++ at least, access control is per-class rather than per-object. That is -- access specifiers are about limiting the scope of the _code_ that knows about (and thus maintains invariants about) the internals of objects. Member functions as a whole are responsible for maintaining the invariants for the internals of objects, so what does it matter whether they are looking through `this` or through some other access path? – Mankarse Apr 01 '13 at 06:22
  • @Mankarse: that's not quite so. see my comments on the questions. – Cheers and hth. - Alf Apr 01 '13 at 06:26
  • @Cheersandhth.-Alf: The non-access to protected members stems from the same idea (the idea that access control is about the scope of _code_ that can see the private/protected members). The scope of access to protected members should be the code in the derived class and in the base class. Code in other derived classes *must* not be able to access them as such code is not in the relevant scope. – Mankarse Apr 01 '13 at 06:29
  • @Mankarse: that's not meaningful, sorry. i suggest you read up on the matter. – Cheers and hth. - Alf Apr 01 '13 at 07:11
  • @Cheersandhth.-Alf: Sorry if I did not make myself sufficiently clear. I read up on the matter (in section 11 of the standard and in TC++PL), and it mostly confirmed the model that I am arguing for. The model that I am arguing for is that C++ access control should be though of in terms of "limitations to the amount of code that must be inspected to see every use of a member (and thus understand its meaning or its invariants)". (tbc) – Mankarse Apr 01 '13 at 08:39
  • If you want to check all uses of a private member, you need only check the code in the class that names that member. (Sure, you have to check for accesses that aren't through `this`, but that doesn't change the amount of code that must be inspected). (tbc) – Mankarse Apr 01 '13 at 08:39
  • If you want to check all uses of a protected non-static member of a particular class(let's call it C), you need only check the code in C, the code in the base class chain that goes up to the class that names the member and the code in classes derived from C.(That is- access to protected members of C is limited to either code that derives from C or code that C derives from (up to the base object that declares the member).Again, and contrary to your comments below, you might have to check for accesses that aren't through `this`, but that doesn't change the amount of code that must be inspected) – Mankarse Apr 01 '13 at 08:40
  • If you want to check all uses of a public member, you need to check every line of code in the entire program. (sorry, but that's the point of public :P) The only thing that does not fit in to this model is access control for static protected members. For static protected members to conform to this model, they would have to have identical semantics to static private members. In my opinion this is simply a hole in the C++ type system that exists because giving the same meaning to private and protected for static members was seen as silly. – Mankarse Apr 01 '13 at 08:40

2 Answers2

4

The concept of access specifiers such as private, public etc. applies to classes, not just objects of classes. If a variable is private in a class, and an object A of that class has a function that takes another object B of the same class, A has access to B's private members since A and B belong to the same class.

Copy constructors rely on this:

#include <iostream>                                                                

using namespace std;                                                            


class A {                                                                       
  public:                                                                       

     A(){val = 1.0;}                                                            

     //copy constructor                                
     A(const A& _other) {                                                       
       val = _other.val; //accessing private member of _other                   
     }                                                                          

    double dist(A _a) {return val - _a.val;} //accessing private member of _other

  private:                                                                      
    double val;                                                                 
};                                                                              


int main() {                                                                    

A a;                                                                            
A b;                                                                            

cout << a.dist(b) << endl;                                                      

}
maditya
  • 8,626
  • 2
  • 28
  • 28
  • this makes sense. Probably i thought that access specifiers were for objects. – aakash Apr 01 '13 at 06:20
  • 1
    well there is a difference between `this` and e.g. method arguments (and other objects) with respect to access checking. on the `this` object you can freely access protected members of a base class. that is not so for other objects, so yes, there is a difference wrt. to which object. – Cheers and hth. - Alf Apr 01 '13 at 06:23
  • @Alf I'm not understanding ... do you mean that class A's function cannot access the protected member of the base class of an object that is passed as a parameter to that function? I seem to be able to ... – maditya Apr 01 '13 at 06:31
  • @maditya: i meant what i wrote, which means that a class A function cannot freely access protected members of a base class object that's passed as parameter. there's no absolute barrier though. the type system of C++ allows access to just about anything if you employ sufficiently intricate low level means (in this case member pointers are sufficient to work around the ordinary access rules). – Cheers and hth. - Alf Apr 01 '13 at 07:17
0

int x, y; are private to the Class Point. It means all the members of Class Point can access,modify it.

The functions and constuctors of Class Point are public i.e Other functions(from some other class etc) [like main] can access them. The idea of OOPS is to keep your data safe, Anyone who wants to modify the values can do it via the public methods of that class. They can't access them directly. This allows you to keep any check for invalid modifications to data [setting invalid values like height = -4; etc]

If u keep int x,y as public [which is not correct OOPs] any function (main etc) can access it and modify the value to something undesirable.

Point p;

p.x = -5 (suppose you only wanted +ve values for x , you can't check if the functions accessing is setting some undesirable value)`

Not a relevant analogy , but still...You have a room in the house which only the family members can access. Any outsider who wishes to keep or remove or do anything to the things in the house has to ask your family members to do it. If u assume even family members are not allowed to access the room [assuming even member functions can't access variables ] then there is no use of keeping anythin in the room [the data cannot be used by anyone]

Suvarna Pattayil
  • 5,136
  • 5
  • 32
  • 59