Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Emulate access specifiers in C

Tags:

c++

c

oop

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 ?

like image 246
Bandicoot Avatar asked Jun 13 '12 03:06

Bandicoot


People also ask

What is the default access specifier in C++?

In a C++ structure type, the default access modifier for class member and member functions is "public".

What is the use of protected access specifier in implementing inheritance in C #?

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.

Where are access specifiers used?

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.


1 Answers

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.

like image 164
Ernest Friedman-Hill Avatar answered Oct 28 '22 09:10

Ernest Friedman-Hill