Я хотел бы создать объект, используемый для хранения данных, ограничивающий доступ для чтения / записи.
Например :
OBJ obj1;
OBJ obj2;
// DataOBJ has 2 methods : read() and write()
DataOBJ dataOBJ1 (obj1);
С кодом выше, я хочу obj1
чтобы получить доступ write()
метод, в то время как другие OBJ
объекты (obj2
в этом случае) следует только получить доступ к read()
метод.
Можно ли создать DataOBJ
класс ограничивает права, как это?
Классический «геттер-сеттер» не соответствует моим потребностям.
Благодарю.
Вы можете контролировать доступ для записи / чтения по глобальной ссылке шаблона obj1 / obj2, как в этом примере:
class OBJ {
};
OBJ obj1;
OBJ obj2;
// RESTRICTED ACCESS
class DataOBJBase {
protected:
void write() {}
void read() {}
};
template <OBJ&>
class DataOBJ;
// ALLOW WRITE IF FOR obj1
template <>
class DataOBJ<obj1> : public DataOBJBase {
public:
using DataOBJBase::write;
};
// ALLOW READ IF FOR obj2
template <>
class DataOBJ<obj2> : public DataOBJBase {
public:
using DataOBJBase::read;
};int main() {
DataOBJ<obj1> dobj1;
dobj1.write(); // cannot read
DataOBJ<obj2> dobj2;
dobj2.read(); // cannot write
}
Я думаю, что вам лучше всего определить интерфейс для read
а также write
методы, и передать объект-оболочку только для чтения (который реализует write
выбрасывая исключение), а не реальный объект для тех, кто не должен получить разрешение на запись.
Имейте в виду, это не мешает вредоносному коду анализировать ваш объект-обертку — если вы хотите это сделать, DataOBJ
должен существовать в другом процессе, чем клиенты, доступные только для чтения, а механизм RPC на границе процесса должен обеспечивать разрешение доступа.
Вы можете сделать это с набором разных классов, с помощью метода «disabled», который выдает исключение.
Что-то вроде:
struct DataInterface
{
virtual void read(...) = 0;
virtual void write(...) = 0;
};
struct DataReadOnly : public DataInterface
{
void read(...) { ... }
void write(...) { throw write_not_allowed(); }
};
struct DataReadWrite : public DataInterface
{
void read(...) { ... }
void write(...) { ... }
};
Мысль у меня есть и, вероятно, плохая практика. Тем не менее, я отвечу на вопрос так, как его спросили, с чем-то, что пришло в голову:
Статические переменные.
class Foo
{
private:
int y;
public:
Foo();
~Foo();
void set(int);
int get(void);
};
Foo::Foo()
{
static int c = 0;
++c;
y = c;
}
Foo::~Foo()
{
--y;
}
int Foo::get(void )
{
if(y == 1)
return y;
else
//do return an error code or something
}
void Foo::set(int r)
{
if(y== 2)
y = r;
else
//Do nothing
}
int main()
{
Foo *x1 = new Foo(); //Gets assigned 1
Foo *x2 = new Foo(); //Gets assigned 2return 0;
}
Редактировать: Для пояснения — я пропустил удаление, и что не так, как логику для правильного уменьшения на уничтожение, так как мой ответ хэширует идею, а не кодирование для OP.