Method Access Restriction

From Schmid.wiki
Jump to: navigation, search

Method Access Restriction

In certain cases, certain members of a class should only be accessible to another class. In C++, this is traditionally handled by the friend keyword. However, since friend doesn't exist in C# and other similar languages, a more common object-oriented approach is desirable.

Example Problem

Let's imagine a class A that has a method restricted_method that only may be accessed by the class Restricted_accessor:

class A {
public:
    int restricted_method();
};

// This class should have a special relationship with A.
class Restricted_accessor {
public:
    int use_restricted(A & a) {
        return a.restricted_method();
    }
};

class Normal_accessor {
public:
    int use_restricted(A & a) {
        return a.restricted_method(); // <- Should not be allowed
    }
};

Using the friend keyword, we could solve the problem like this:

class A {
private:
    friend class Restricted_accessor;
    int restricted_method();
};

class Restricted_accessor {
public:
    int use_restricted(A & a) {
        return a.restricted_method();
    }
};

class Normal_accessor {
public:
    /*
    int use_restricted(A & a) {
        return a.restricted_method(); // <- Not allowed.
    }
    */
};

Solution

We can use an interface where restricted_method is public and then make it private in all derived classes.

class Restricted_interface {
public:
    virtual int restricted_method() = 0;
};

class A : public Restricted_interface {
private:
    virtual int restricted_method() { return 7; }
};

class Restricted_accessor {
public:
    int use_restricted(Restricted_interface & r) {

	// Since restricted_method is public in the 
	// Restricted_interface, we can access it:
        return r.restricted_method();
    }
};

class Normal_accessor {
public:
    /*
    int use_restricted(A & a) {
        return a.restricted_method(); // <- Not allowed
    }
    */
};

int main() {

    A a;
    Restricted_accessor ra;

    // Fine, uses a through restricted interface.
    return ra.use_restricted(a);
}

The solution is not perfect, the restricted_method may still be accessed by dynamic_casting an A instance to a Restricted_interface and accessing it from there.

Personal tools