1

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.

Patouf
  • 119
  • 4
  • 15
  • 1
    This should depend on what? The names of the variables? – Luchian Grigore Oct 15 '12 at 10:45
  • @LuchianGrigore There's no way to do that ? Combination of attorney/client idiom + friend keyword ? ^^ – Patouf Oct 15 '12 at 10:50
  • Could you tidy up your example? Right now it looks like `DataOBJ` is a function, it is not really clear what you mean. – Benjamin Bannier Oct 15 '12 at 10:51
  • Are obj1, obj2 global objects? – PiotrNycz Oct 15 '12 at 10:51
  • @PiotrNycz they are not, but can be. – Patouf Oct 15 '12 at 10:52
  • Then see my answer for global objects. Let me know if I understood your question correctly. My solution is only for global objects. – PiotrNycz Oct 15 '12 at 11:12
  • Do you want the restriction to work at compile time, so the program will fail to compile if obj2 tries to access read() ? Or, is a runtime error sufficient so that some kind of exception will be thrown at runtime if obj2 tries to access read which will will either need to be handled, or the program will crash. – Scott Langham Oct 15 '12 at 11:41
  • @ScottLangham At compile time would be perfect, but a throw exception is fine too. All I want is a way to do that "getter setter" object. :) – Patouf Oct 15 '12 at 13:49

4 Answers4

0

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.

Simon Richter
  • 28,572
  • 1
  • 42
  • 64
0

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(...) { ... }
};
Some programmer dude
  • 400,186
  • 35
  • 402
  • 621
  • How can I use these structs within my `OBJ` objects ? – Patouf Oct 15 '12 at 10:56
  • 1
    @Patouf With that I can't help you, as I don't know what you want to do with the `read` and `write` functions. I just showed a general way of having classes that disallows certain operations. – Some programmer dude Oct 15 '12 at 10:59
  • `DataOBJ` is a template class `template `, with a private attribute `mydata mydata_`. `write(mydata& data)` sets the data into `mydata_`, while `read(mydata& data)` retrieves the value of `mydata_`. – Patouf Oct 15 '12 at 13:34
0

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.

M4rc
  • 473
  • 2
  • 13
0

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
}
PiotrNycz
  • 23,099
  • 7
  • 66
  • 112
  • With this method I must specify the read or write access for each `OBJ`. Is there a way to 'automate' that ? If `DataOBJ`, then `obj1` is the only `OBJ` having write access ? – Patouf Oct 15 '12 at 13:40
  • Yes, with this way you have to do for each object. – PiotrNycz Oct 15 '12 at 14:08
  • Can your objects be of different types? I mean `ObjWithReadAccessToData obj1;`, `ObjWithWriteAccessToData obj2;`? Both deriving from Obj : `class ObjWithReadAccessToData : public Obj`? – PiotrNycz Oct 15 '12 at 14:10
  • No they can't. Look at this case : `DataOBJ dataOBJ1 (obj1); DataOBJ dataOBJ2 (obj2);`. Here, `obj1` can write into `dataOBJ1`, `obj2` can write into `dataOBJ2`, and both can read the two dataOBJs. – Patouf Oct 16 '12 at 09:14
  • Update your question - show exact example with lines which shall compile and lines which shall not. I mean show the usage of this read/write access - maybe I misunderstood your question somehow – PiotrNycz Oct 17 '12 at 14:47