Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

CRTP - Can I make a private method?

I'm implementing a static polymorphism:

template<typename T>
class Base {
public:
    void method() {
         // do something
         impl();
         // do something else
    }
    void impl() { // intended to be private
        static_cast<T*>(this)->impl();
    }
};

class Derived : public Base<Derived> {
public:
     void impl() { // intended to be private
     }
};

This code is a static implementation of a dynamic polymorphic classes where void impl() was virtual and private.

I've achieved polymorphism (static). But I had to make the method void impl() public in order to allow access to it from a Base class. I want method void impl() to be private again. Can it be done?

UPDATE: I don't want to write

friend class Base<Derived>;

in Derived class, because it allows Base access to all members of Derived.

like image 431
beginpluses Avatar asked May 26 '19 14:05

beginpluses


1 Answers

Adding a line to your Derived class:

class Derived : public Base<Derived> {
public:
private:
     void impl() { // intended to be private
     }
     friend class Base<Derived>;
};

which will specify the base class as a friend, allows me to compile the code with impl being private.

EDIT

As suggested in the comment by @Oliv, the implementation of the Attorney-Client idiom would look like:


template<typename T>
class Attorney;

template<typename T>
class Base {
public:
    void method() {
        // do something
        impl();
        // do something else
    }
private:
    void impl() { // intended to be private
        Attorney<T>::impl(*static_cast<T*>(this));
    }
};


class Derived : public Base<Derived> {
private:
    void impl() { // intended to be private
    }
    friend class Attorney<Derived>;
};

template<typename T>
class Attorney {
private:
    friend class Base<Derived>;

    static void impl(Derived & c) { // add additional parameters as needed by impl
        c.impl();
    }
};

like image 173
Riddick Avatar answered Oct 20 '22 22:10

Riddick