Specific “getter setter” dedicated object
-
07-07-2021 - |
Question
I'd like to create an object used to store data, restricting read/write access.
For example :
OBJ obj1;
OBJ obj2;
// DataOBJ has 2 methods : read() and write()
DataOBJ dataOBJ1 (obj1);
With the code above, I want obj1
to access write()
method, while other OBJ
objects (obj2
in this case) should only access the read()
method.
Is it possible to create a DataOBJ
class restricting rights like that ?
The classical "getter setter" does not suit my needs.
Thanks.
Solution
You can control access to write/read by template global reference obj1/obj2 like in this example:
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
}
OTHER TIPS
I think your best bet is defining an interface for the read
and write
methods, and pass a read-only wrapper object (which implements write
by throwing an exception) rather than the real object to anyone who should not get write permission.
Mind you, this does not stop malicious code from dissecting your wrapper object -- if you want to do that, the DataOBJ
should live in a different process than the read-only clients, and the RPC mechanism at the process boundary needs to enforce the access permission.
You could do it with a set of different classes, with the "disabled" method throwing an exception.
Something like:
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(...) { ... }
};
A thought I have and is probably bad practice. Nevertheless, I'll answer the question as asked with something that came to mind:
Static variables.
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 2
return 0;
}
Edit: For clarification -- I left out the delete's, and what not as well as the logic for properly decrementing on the destruction as my answer is hashing an idea out there, versus coding for the OP.