Is it possible to emulate C++ access specifiers [public, private, protected] in C ? More generally, how does the C++ compiler ensure that private members of a class are not accessed by non-member functions ?
In a C++ structure type, the default access modifier for class member and member functions is "public".
The protected access specifier hides its member variables and functions from other classes and objects. This type of variable or function can only be accessed in child class. It becomes very important while implementing inheritance.
Access Modifiers or Access Specifiers in a class are used to assign the accessibility to the class members, i.e., they set some restrictions on the class members so that they can't be directly accessed by the outside functions.
C++ access control is entirely a figment of the compiler's imagination: you can't access a private member only because the compiler will refuse to compile any code that tries to do so.
It's actually fairly simple to access a private member of a C++ class by tricking the compiler into thinking that a pointer to an instance of ClassWithPrivateMember
is actually a pointer to an instance of ClassWithPublicMember
-- i.e., by using a slightly modified header file, you can generally get access to things you shouldn't. Not that anyone ever does anything like that...
The best way to do access control in C is by passing around pointers to an opaque type: struct
objects the definition of which is not available to client code. If you provide a foo* create_foo()
method and a series of methods that operate on foo*
, hiding the actual definition of foo
from the client, then you'll have achieved a similar effect.
// File "foo_private.h"
struct foo {
int private1;
char private2;
};
// File "foo.h"
typedef struct foo foo;
foo * create_foo(int x, char y);
int mangle_foo(foo *);
// file "foo.c"
#include <stdlib.h>
#include "foo.h"
#include "foo_private.h"
foo * create_foo(int x, char y) {
foo * f = (foo *) calloc(1, sizeof(foo));
f->private1 = x;
f->private2 = y;
}
int mangle_foo(foo *f) {
return f->private1 + f->private2;
}
Now, you distribute foo.c
compiled into a library, along with foo.h
. The functions declared in foo.h
form the public interface of a type, but the internal structure of that type is opaque; in effect, the clients who call create_foo()
can't access the private members of the foo
object.
Our friend the FILE*
is a similar sort of thing, except that the type FILE
isn't usually truly opaque. It's just that most people (wisely) don't go poking through its innards. There, access control is enforced merely by obscurity.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With