Дружеский миксин шаблон? - PullRequest
       7

Дружеский миксин шаблон?

2 голосов
/ 27 января 2010

Скажем, у меня есть два класса Foo и Bar, и я хочу подружиться с Foo Bar без изменения Foo. Вот моя попытка:

class Foo
{
    public:
        Foo(){}

    private:
        void privateFunction(){}
};

template <class friendly, class newFriend>
class friends : public friendly
{
    private:
        friend newFriend;
};

class Bar
{
    public:
        Bar(){}

        void callFriendlyFunction()
        {
            friendlyFoo.privateFunction();
        }

    private:
        friends<Foo, Bar> friendlyFoo;
};

int main(int argc, char* argv[])
{
    Bar bar;

    bar.callFriendlyFunction();

    return 0;
}

Получение ошибки компилятора при попытке вызвать приватную функцию, поэтому, очевидно, это не сработало. Есть идеи?

Ответы [ 3 ]

2 голосов
/ 27 января 2010

Это не работает, потому что friends в любом случае не имеет доступа к privateFunction, потому что это private (классы-потомки не имеют доступа к закрытым полям в любом случае). Если бы вы объявили privateFunction как protected, это сработало бы.

Вот отличная статья о Mixins в C ++. (PDF ссылка)

1 голос
/ 27 января 2010

Только класс может объявить, кто его друзья. Их нельзя вводить извне. Это просто имеет смысл: если бы это было разрешено языком, он мог бы вообще забыть о приватном ключевом слове, ведь любой код, предназначенный для доступа к приватным членам, мог просто использовать этот трюк. Обратите внимание, что добавление отношения «друг» в производный объект не поможет, так как метод недоступен из производного шаблона.

Любой другой подход, который вы можете попробовать, является хакерским и непереносимым (переписывание того же заголовка с изменением private для public, похоже, будет работать во многих ситуациях, но в некоторых угловых случаях оно не будет работать).

Также обратите внимание, что в шаблоне класса вы не можете объявить аргумент типа как друга, это явно запрещено в текущем стандарте, даже если это ограничение будет снято в следующем стандарте.

0 голосов
/ 27 января 2010

Вы, вероятно, должны сделать

void privateFunction(){}

защищены.

Упс, я забыл, что вы не можете изменить Foo. Другого пути нет, афаик.

...