Является ли этот ориентированный на ключ шаблон защиты доступа известной идиомой? - PullRequest
46 голосов
/ 10 июля 2010

Матье М. поднял шаблон для защиты доступа в этом ответе , который я видел раньше, но никогда не рассматривал шаблон сознательно:

class SomeKey { 
    friend class Foo;
    SomeKey() {} 
    // possibly make it non-copyable too
};

class Bar {
public:
    void protectedMethod(SomeKey);
};

Здесь только у friend класса ключей есть доступ к protectedMethod():

class Foo {
    void do_stuff(Bar& b) { 
        b.protectedMethod(SomeKey()); // fine, Foo is friend of SomeKey
    }
};

class Baz {
    void do_stuff(Bar& b) {
        b.protectedMethod(SomeKey()); // error, SomeKey::SomeKey() is private
    }
};

Он позволяет более тонко-гранулированный контроль доступа, чем Foo a friend из Bar, и позволяет избежать более сложных шаблонов прокси.

Кто-нибудь знает, есть ли у этого подхода имя, т. Е. Является известным шаблоном?

Ответы [ 4 ]

12 голосов
/ 28 апреля 2014

Благодаря ваш другой вопрос похоже, что этот шаблон теперь известен как шаблон "пароля".

В C ++ 11 он становится еще чище, потому что вместо вызова

b.protectedMethod(SomeKey());

Вы можете просто позвонить:

b.protectedMethod({});
7 голосов
/ 10 июля 2010

Кажется, что эта идиома, подобная той, которая упоминается в другом вопросе здесь .Он называется «Адвокат-клиент» и описан более подробно там .

2 голосов
/ 19 сентября 2014

такой скучный человек, как я, сделал бы код из птицы:

int FraudKey=0;
b.protectedMethod(reinterpret_cast<SomeKey&>(FraudKey));
0 голосов
/ 18 декабря 2014

Это довольно близко к этому:

http://minorfs.wordpress.com/2013/01/18/raiicap-pattern-injected-singleton-alternative-for-c/

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

Таким образом, как говорится в статье, если вы используете этот ключ вместе с теми конструкторами, для которых может иметь смысл управление доступом, объектами, представляющими значительную часть ресурсов scares, которые в C ++ обычно реализуются как объекты RAII,чем название RAIICap или RAII-Capability действительно имело бы смысл.

http://www.eros -os.org / essays / capintro.html

В качестве альтернативы вы можете ссылаться на него с более общим именем, таким как полномочия на создание.

Реализация, описанная в этой статье, имеет много общего с основным, то есть основным должно быть создание всех ключей доступа.Вы можете расширить его и сделать его более гибким, добавив дополнительный открытый конструктор для самого ключа:

template <typename T>
class construct_authority {
  public:
    construct_authority(construct_authority<void> const&)
    friend int main(int,char **);
  private:
    construct_authority(){}
};

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

Лично я считаю, что имя RAIICap вполне подходит для полезной части этого паттерна.

Некоторое время назад я предложил добавить этот простой шаблон выше в стандартную библиотеку.

https://groups.google.com/a/isocpp.org/forum/#!topic/std-proposals/p_v-aYIvO1E

К сожалению, существуют проблемы с идеей, что может быть один основной отпечаток, который составляет вычислительный корень, поэтому что-то подобное, по-видимому, не может быть в стандартной библиотеке,Сказав это, по крайней мере, для использования с конструктором классов RAII, этот шаблон кажется весьма полезным.

...