Sign in to follow this  

Access Modifiers -- What's The Point? (Solved)

This topic is 4716 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I've been experimenting with C++, and it seems that access modifiers (i.e. public/private) do nothing to change the underlying machine code that is produced and can easily be circumvented. It seems to me that they are merely a comment, and if that's the case why do we have them at all? "//" comments should do the job just as well. I've come to the conculsion that the only way to protect data, is to keep it unknown. That is, to make sure that the user doesn't have enough information about the data to make use of it. For example, while internally a class contains "int var1, var2, var3;", on the external frontend that the user manipulates the same code is shown as "char data[12];". This to me is the only true private data. So, as the topic states, what the point of access modifiers? imho, they can only serve to make a language overly complex. [Edited by - DudeMiester on January 16, 2005 12:38:26 PM]

Share this post


Link to post
Share on other sites
Not if you're smart you wont. For example:

class A
{
private:
int var1;
};

You want access to that var1?

class B
{
public:
int var2;
};

Then do:

A Test;
B* Test2=(B*)&Test;

Now you have access.

As I already stated, no data is hidden unless you hide the information about that data.

Share this post


Link to post
Share on other sites
Access modifiers are there to prevent people from messing with class data you want to keep out of them.
For example in string class - there's some storage for length of string. But if this is public, user can alter it and create unusable instance of class. This value should change only when you create/add/delete strings. So you need a way to say compiler, that this data is only accessible from within the functions defined in class (or friends of class) - so you put private/protected there.
As the names of modifiers say: public is for public use, so user won't screw anything when messing with public data. Private and protected members are for internal use only.
The difference between private and protected is how they behave in derived classes. Private members are not accessible from derived classes, protected are.

Share this post


Link to post
Share on other sites
True, but that's still merely a comment, like I stated. You're only saying, "I'd rather you not touch this data", which is done equally well by the code:

//I'd rather you not touch this data
int var;

EDIT:

I have the same issue with const, because with const_cast it no longer has any meaning. It too is merely a comment. I believe comments should be comments, code should be code, and the two shouldn't be mixed up.

Share this post


Link to post
Share on other sites
The point of access modifiers is to separate the public API which maintains class invariants and the private implementation which, if called externally, may not. They are stronger than comments because they can be enforced by the compiler. Of course you can get round them if you're going to get downright Machiavellian, but that's no reason not to have them. Should we abolish taxes just because rich people with well paid lawyers manage to get around them occasionally?

I'd recommend reading Uses and Abuses of Access Rights.

Enigma

Share this post


Link to post
Share on other sites
Don't think access modifiers are necessary? Consider this code:

class List
{
public:

class Node;
class Iterator;

Node* head;
int size;

List() : head(0), size(0) {}

Iterator add(int value);
void remove(Iterator node);
// etc.
};


void func1(List* list)
{
// do stuff if the list is empty
if(list->size=0)
{

}
}

void func2()
{
List list;
list.add(5);
func1(&list);
}




A very easy mistake to make, a very nasty bug to find.

EDIT: Well, any good compiler will spit a warning at you about this, but it's a good example of why access modifiers are necessary.

Share this post


Link to post
Share on other sites
So the basic idea is that while they are essentially "special" comments, they help avoid causing mistakes by messing with data you shouldn't be.

You see I'm coming from the direction of someone who wants to get access to that data, despite it's private nature. In that case, the method I mentioned is the only thing you can do to protect it. Even then you can probably reverse engineer it anyways, but it would be much more difficult and involving going through a lot of dis-assembly.

You see I'm writing some stuff that gives you detailed run time type information on classes, and I was wondering if it's worth differentating between public and private data and including logic to check access and whatnot. But then I realised you can get access anyways, so forget it. The only way to have really private data is to have no information on it. So I'm probably going to just set it up, so you can pick and choose what data in your class to have run-time info on. This creates a kind of public interface, that external classes can use to manipulate the class without actually knowing it's type.

Share this post


Link to post
Share on other sites
Quote:
they help avoid causing mistakes by messing with data you shouldn't be

Exactly.

Quote:
You see I'm coming from the direction of someone who wants to get access to that data, despite it's private nature. In that case, the method I mentioned is the only thing you can do to protect it. Even then you can probably reverse engineer it anyways, but it would be much more difficult and involving going through a lot of dis-assembly.

Well in cases where you don't want the variables to be visible even when looking at the header you can use the PIMPL (Private IMPLementation) design pattern (which can also be used when the exact details of the data, implementation, whatever aren't even known to the class). Here's an example:

Public header:

class MyClassImpl;

class MyClass
{
public:

MyClass();

// Interface functions, etc.

private:

// Implementation
MyClassImpl* impl;
};



Private source:

#include "MyClass.h"


class MyClassImpl
{
public:
int var1;
int var2;
};


MyClass::MyClass()
: impl(new MyClassImpl)
{
// you can now access your private data
// like this
impl->var1 = 0;
impl->var2 = 0;
}


Share this post


Link to post
Share on other sites
Quote:
Original post by joanusdmentia
Don't think access modifiers are necessary? Consider this code:
*** Source Snippet Removed ***
A very easy mistake to make, a very nasty bug to find.

EDIT: Well, any good compiler will spit a warning at you about this, but it's a good example of why access modifiers are necessary.

i dont see the mistake/bug

Share this post


Link to post
Share on other sites
Quote:
Original post by DudeMiester
So the basic idea is that while they are essentially "special" comments, they help avoid causing mistakes by messing with data you shouldn't be.

You see I'm coming from the direction of someone who wants to get access to that data, despite it's private nature. In that case, the method I mentioned is the only thing you can do to protect it. Even then you can probably reverse engineer it anyways, but it would be much more difficult and involving going through a lot of dis-assembly.


No offence, but you seem to have missed the point of encapsulation. Even Stroustrop said it's intended as an aid to good programming not a security measure. If any half decent programmer wants to change that data, of course they can do it, but they'd be an idiot. The whole point is that you don't need to know what data the class is using internally. If you find yourself really needing to access private data, I'd advise you to put down the compiler and step away from the code [smile]

Share this post


Link to post
Share on other sites
Quote:
Original post by Alpha_ProgDes
i dont see the mistake/bug


The comparison in func1, I left out an '=' so it's an assignment inside the if() instead of a comparison. Like I said, easy mistake to make [smile]

Share this post


Link to post
Share on other sites
Quote:
Original post by DudeMiester
True, but that's still merely a comment, like I stated. You're only saying, "I'd rather you not touch this data", which is done equally well by the code:

//I'd rather you not touch this data
int var;


(Edit: ok, everyone else said this paragraph already, basically. Oh well.) The compiler understands "private". It does not understand "// I'd rather you not touch this data". The mechanism is there so that the compiler can help you to not make mistakes; it is not there to guard against you doing something deliberately malicious. You might as well ask why the compiler allows you to cast a B* to an A* (and worse, actually lets you use a C-style cast instead of requiring reinterpret_cast<>). But if someone accidentally makes use of 'var' (and it can happen; either from overlooking the comment, or some kind of name collision issue), the compiler can't detect the problem.

Of course, if you are disciplined enough that your data is always "treated privately" anyway (i.e. noone will have the temptation to use var in the wrong place because it's data, and such things just aren't done with data members on your project), feel free to toss away the safety net. Or so say some people, anyway.

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
Smalltalk gets by pretty well with all messages public and all instance variables protected. If a message is labelled "no touchie" and you touchie and get burned... well... "Told ya so". It's generally assumed if someone's messing with the private messages that they need that functionality and know the consequences.

Share this post


Link to post
Share on other sites
Of course you can gain access to the private variables. You can change them and make the class unusable and you program crash. Then you can shout "har, har - I hacked my own program so it doesn't run anymore". But do you really want to hack your program so it doesn't run anymore? The point is if you accidentaly do something that would make your program crash (changing variable that shoudln't be changed from the outside), the compiler will tell you. If you only put a comment there, you have a non-working program.

That's the point - it is a note to the compiler it should tell you, you're doing something you've considered stupid.

Oxyd

Share this post


Link to post
Share on other sites
It's essentially a piece of advise to the programmer using the class saying "these members are part of the implementation, please do not modify them except by official means".

Yes, an unscrupulous programmer can easily mess with your private variables, but if their code breaks later, they deserve all they get.

The compiler won't normally compile code which attempts to access private variables in an invalid context. This serves to suggest to the programmer that they're doing something wrong.

Mark

Share this post


Link to post
Share on other sites
Here's another reason why you should use access modifiers. You will never hold a real programming job if you don't. Your boss will be like, "Jesus Christ son, where did you learn C++?!" and then kick you out of the office. With a steel-toed boot. And all the other programmers will wheeze at you while pushing their glasses up their nose, and then kill your D&D character.

Seriously though, we use these constructs for the same reason we use C, C++, Java, etc., and every other high-level language. These things make it easier for humans to visualize their code as more than just a linear sequence of machine instructions. As far as access modifiers in particular are concerned... well, think of it this way. Every time you want your CD player (or shall I say iPod in this day and age) to play, you don't crack the thing open and push the laser (or HDD head) around yourself, now do you? Of course not, those things were made "private" so that users like yourself wouldn't mess around with them. Of course you could still technically mess around with it if you wanted to, but that will void your warranty and it would serve no real purpose other than to demonstrate that it's indeed possible - a moot point since it's blatantly obvious. Unless it were in some sort of NASA alloy container or something. Instead, you have "public" buttons that serve the purpose you want.

You'll notice a common thread between using public/private access modifiers, and distinguishing between interfaces and implementation. It's not a coincidence, it's intentional. And as every good computer scientist will tell you, abstraction makes the world go 'round. And helps you hold a real job.

Share this post


Link to post
Share on other sites

This topic is 4716 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this