Skip to main content
GameDev.net gamedev.net
🔒 Locked

on 3.5.2 - Accessibility domains

Started by algumacoisaqualquer Jul 19, 2007 at 10:08 PM 13 replies 1.8k views
Original Post
algumacoisaqualquer
algumacoisaqualquer
It is said in the end that, although a class inherits the private members from it's base, it cannot access them. Then it proceeds with the following example:

class A
{
	int x;
	static void F(B b) {
		b.x = 1;		// Ok
	}
}
class B: A
{
	static void F(B b) {
		b.x = 1;		// Error, x not accessible
	}
}


I understand that class A can access a private member of class B but my question is: why? Doesen't it breaks the idea o private a little bit? Extrapolating from this, let's say we have a recursive class, something like:

class A
{
	int x;
	A some_member;
	void F() { //I removed the static, because he is accessing a non-static member.
		some_member.x = 1;		// Ok?
	}
}


Whould that also be possible? I mean, it compiled fine, but I didn't tried to actually call the function.
TheTroll
TheTroll
In your example some_member is just an instance of Class A, so it would have access to all private members in itself.

As for your private access question. Private means it can be accessed only in the class it was created in. For inherited classes you use protected if you want to directly access them.

[opinion]
I am not that fond of protected members, it has a bad habit of breaking encapsulation and ends up causes errors that are rough to hunt down. The nice thing about keeping things private is that only the class that holds them can change them, that means if something goes wrong you know exactly where to look. If you have a bunch of inherited class, or a chain of inheritance and something goes wrong with the data then you have a lot of places to look. So when ever possible I try to keep it all data members private.
[/opinion]

theTroll
algumacoisaqualquer
algumacoisaqualquer
Quote:
Original post by TheTroll
In your example some_member is just an instance of Class A, so it would have access to all private members in itself.

As for your private access question. Private means it can be accessed only in the class it was created in. For inherited classes you use protected if you want to directly access them.
theTroll


Ok, I see it. It's just that I used to believe that a private member was only accessible inside the object (I mean, the instance of a class) that owned it. However, it looks like a private member is accessible by the class were it's defined. I had never realised there was a diference in that. Is this what is happening here?
Thanks for the answer!

TheTroll
TheTroll
Correct. It is able to be accessed by the instance of that class.

public class foo{   private int my_int;   public float my_float;   private foo my_foo;   public void ChangeInt(int in)   {      my_int = in;  // private but part of this instance.      my_foo.ChangeInt(in);  // public, can access.      my_foo.my_int = in;   // not valid, this instance does not have access to the private member of the instance my_foo;      my_float = (float)in;  //valid, it is public;      my_foo.my_float = (float)in;  // valid this is a public member in my_foo instance, so you can directly access it.   }}


Does that clear it up?
theTroll
algumacoisaqualquer
algumacoisaqualquer
Actually, the problem is that your example will compile with no problems, even the line:
my_foo.my_int = in;   // not valid, this instance does not have access to the private member of the instance my_foo;


And this was actually my concearn - take the following exemple:
public class foo{   private int iteration;   private foo my_foo;    foo()    {        iteration = 8;        my_foo = new foo(8);    }    foo(int passed_iteration)    {        iteration = passed_iteration - 1;        if(iteration > 0)            my_foo = new foo(iteration);    }    public int get_my_foo_iteration()    {        if (iteration > 0)            return my_foo.iteration; //note we are returning not from this.iteration, but rather from this.my_foo.iteration, wicth is private        else            return 0;    }    static void Main()    {        foo some_foo = new foo();        Console.WriteLine(some_foo.my_foo.my_foo.get_my_foo_iteration());    }}

So, basically, we are accessing a private member from another instance of the same class, it seems to be perfectly valid. However, I also believe it shouldn't be valid, but aparently, it is.
savagemonitor
savagemonitor
Okay, within static methods I can understand that private members could be modified (since all of the instances share that static method). However, according to the specification, private members are accessible from within the text of the class in which they are defined. So the second example works since some_member is of the type A in the text of the class definition of A.

[opinion]
This is pretty dumb, IMO, as the purpose behind private members is to keep outsiders (other instances) from using them. However, I doubt that the programmers were expecting a programmer to have a class reference an instance of itself or any child classes within itself. I also checked this, and my latest version of Java allows the same thing, so I'm guessing that it's something that the language can do that no one really wants or ever does.
[\opinion]

I guess the only constructive thing that I can tell you is to never have an class that has as a member an instance of that class (or any child classes).

[Edited by - savagemonitor on July 20, 2007 2:55:27 AM]
TheTroll
TheTroll
class Regression    {        private int A;        private Regression reg;        public Regression()        {                    }        public void ModifyA(int a)        {            A = a;            if (reg == null)                reg = new Regression();            reg.A = a;        }


I just tested this and directly calling the Private member A is perfectly valid. I would have sworn that was not legal. No idea what they were thinking with that. I really think it is a bad idea. I have never tried it that is why I didn't think it would work. Sorry about the confusion.

theTroll
JWalsh
JWalsh
C++, Java, C#, and most other OO languages allow you to access the private members of an object, from another object of the same class. For example...

class MyClass{    public MyMethod(MyClass input)    {        // PrivateInt is accessible by input, but also any other        // object of type 'MyClass'        input.PrivateInt = 10;        }    private int PrivateInt;}


The reason: To allow copy constructors, deep copy assignment, etc...If no other object could access the private members of an object, how would you ever make an exact copy? You would either need a 'get' for every single field, or in the case of an internal clone method you would need a 'set' for every single field. Neither of which is particularly desirable.

Also, it doesnt really effect encapsulation as the primary motivator of encapsulation is implementation hiding. That is, classes which consume your class/object shouldn't need to know about its internal workings. However, a class knowing its own internal workings is perfectly fine, as any changes will be implicitly recorded because uhh...it's the same class. =)

So conclusion: It doesnt really violate encapsulation, and it allows for deep copies and member-wise clones, without having to provide 'getters' or 'setters' for every field - which ironically, increases encapsulation.

Cheers!
Mike.Popoloski
Mike.Popoloski
Quote:
Original post by TheTroll
*** Source Snippet Removed ***

I just tested this and directly calling the Private member A is perfectly valid. I would have sworn that was not legal. No idea what they were thinking with that. I really think it is a bad idea. I have never tried it that is why I didn't think it would work. Sorry about the confusion.

theTroll


This is actually very useful. For example, I was writing a class that I wanted to be able to load from a file. Because many .NET types implement a static FromStream or FromFile method, I decided to do the same. Now, in that static method, I can set each field of the class from the data loaded from the file, even though the fields are private.
Mike Popoloski | Journal | SlimDX
TheTroll
TheTroll
Guess I never thought about the deep copy part. Gee, even theTroll learns something.

thanks.
theTroll
Alpha_ProgDes
Alpha_ProgDes
//In the exampleclass A {...}public class B: A {...}//the B class results in a compile-time error because A is not at least as accessible as B.//Likewise, in the exampleclass A {...}public class B{	A F() {...}	internal A G() {...}	public A H() {...}}//the H method in B results in a compile-time error because the return type A is not at least as accessible as the method.


A is internal and B is public. So I understand that B is more accessible than A. But then shouldn't every method in class B give a compile error? F() is accessible by an object but will return an A object that is seen only by code in the same assembly as A. G() is only accessible within the assembly and H() is public so I figured it can be seen by everyone.

What am I missing here?
Beginner in Game Development?  Read here. And read here.  
TheTroll
TheTroll
What do you need help with?

theTroll
JWalsh
JWalsh
F and G are both private, and G is also Internal.

As a result, people using class B are not granted access to class A via those methods.

H is throwing an error because it grants access to an internal class via a public class, which violates the accessibility rules.

Cheers!

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.