By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
458,108 Members | 1,657 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 458,108 IT Pros & Developers. It's quick & easy.

Permitting access to only a subset of the public methods

P: n/a
Hi,

I'm not sure if i'm asking the question correctly but anyway here it
is.

Say I have 3 classes - class A, class B, class R.
1) A and B are the building blocks and R is like a repository that
stores objects of A and B.
2) A is at the lowest level and should "know about" only other As. B
should know only about As and other Bs.
3) R has 3 types of public methods - (i) methods to add A,B (ii)
methods to access A, B and (iii) all other methods.

For now I pass a pointer to R to both A and B so that they can access
information from R as required. However, this exposes all public
methods (ie., (i), (ii) and (iii)) of R to both A and B.

How do I change it so that A and B can only access methods of type
(ii)? (The rationale is that A/B will never add another A/B and they
shouldn't be doing anything else related to R). Is there a way to make
a subclass of R called Rsub and pass that pointer to A,B? Is that a
good way to do it?

I have included code below.

Thanks.
#include <iostream>
#include <vector>

using namespace std;

class A;
class B;
class R;

class A {
public:
A (R* r, const int& i) : rp(r), N(i) {}
int getN (void) const { return N; }
void fA (const int& idx)
{
// Access an A object at index idx through rp
}
private:
R* rp;
int N;
};

class B {
public:
B (R* r, const string& s) : rp(r), str(s) {}
string getStr (void) const { return str; }
void fB1 (const int& idx)
{
// Access an A object at index idx through rp
}
void fB2 (const int& idx)
{
// Access a B object at index idx through rp
}
private:
R* rp;
string str;
};

class R {
public:
// Methods to add A, B
// void addA (const int& i) { A a(i); vA.push_back(a); }
// void addB (const string& s) { B b(s); vB.push_back(b); }
void addA (const A& a) { vA.push_back(a); }
void addB (const B& b) { vB.push_back(b); }

// Methods to access information for A,B
int getAN (const int& idx) const { return vA.at(idx).getN(); }
string getBstr (const int& idx) const { return
vB.at(idx).getStr(); }
// ... some more info

// All other methods
// ...
private:
vector<AvA;
vector<BvB;
};

int main() {
R rep;

A a1(&rep, 100);
A a2(&rep, 200);
rep.addA(a1);
rep.addA(a2);
cout << rep.getAN(0) << " and " << rep.getAN(1) << endl;

// a2.fA(0); // should return info about a1

B b1(&rep, "dog");
B b2(&rep, "cat");
rep.addB(b1);
rep.addB(b2);
cout << rep.getBstr(0) << " and " << rep.getBstr(1) << endl;

// b2.fB1(0); // should return info about a1
// b2.fB2(0); // should return info about b1

return 0;
}
Jul 17 '08 #1
Share this Question
Share on Google+
2 Replies


P: n/a
fg*********@gmail.com wrote in news:e790868e-086d-4cb4-bb40-
2c**********@w7g2000hsa.googlegroups.com:
Hi,

I'm not sure if i'm asking the question correctly but anyway here it
is.

Say I have 3 classes - class A, class B, class R.
1) A and B are the building blocks and R is like a repository that
stores objects of A and B.
2) A is at the lowest level and should "know about" only other As. B
should know only about As and other Bs.
3) R has 3 types of public methods - (i) methods to add A,B (ii)
methods to access A, B and (iii) all other methods.

For now I pass a pointer to R to both A and B so that they can access
information from R as required. However, this exposes all public
methods (ie., (i), (ii) and (iii)) of R to both A and B.

How do I change it so that A and B can only access methods of type
(ii)? (The rationale is that A/B will never add another A/B and they
shouldn't be doing anything else related to R). Is there a way to make
a subclass of R called Rsub and pass that pointer to A,B? Is that a
good way to do it?

I have included code below.

Thanks.
#include <iostream>
#include <vector>

using namespace std;

class A;
class B;
class R;

class A {
public:
A (R* r, const int& i) : rp(r), N(i) {}
int getN (void) const { return N; }
void fA (const int& idx)
{
// Access an A object at index idx through rp
}
private:
R* rp;
int N;
};

class B {
public:
B (R* r, const string& s) : rp(r), str(s) {}
string getStr (void) const { return str; }
void fB1 (const int& idx)
{
// Access an A object at index idx through rp
}
void fB2 (const int& idx)
{
// Access a B object at index idx through rp
}
private:
R* rp;
string str;
};

class R {
public:
// Methods to add A, B
// void addA (const int& i) { A a(i); vA.push_back(a); }
// void addB (const string& s) { B b(s); vB.push_back(b); }
void addA (const A& a) { vA.push_back(a); }
void addB (const B& b) { vB.push_back(b); }

// Methods to access information for A,B
int getAN (const int& idx) const { return vA.at(idx).getN(); }
string getBstr (const int& idx) const { return
vB.at(idx).getStr(); }
// ... some more info

// All other methods
// ...
private:
vector<AvA;
vector<BvB;
};

int main() {
R rep;

A a1(&rep, 100);
A a2(&rep, 200);
rep.addA(a1);
rep.addA(a2);
cout << rep.getAN(0) << " and " << rep.getAN(1) << endl;

// a2.fA(0); // should return info about a1

B b1(&rep, "dog");
B b2(&rep, "cat");
rep.addB(b1);
rep.addB(b2);
cout << rep.getBstr(0) << " and " << rep.getBstr(1) << endl;

// b2.fB1(0); // should return info about a1
// b2.fB2(0); // should return info about b1

return 0;
}
Well, the first thing that comes to mind is to use interfaces.

class IR_A {
public:
virtual void addA(const A& a) = 0;
virtual int getAN(const int& idx) = 0;
virtual ~IR_A(){}
};

class IR_B {
public:
virtual void addB(const B& b) = 0;
virtual string getBstr(const int& idx) = 0;
virtual ~IR_B(){}
};

class R : public IR_A, public IR_B {
public:
// Methods to add A, B
// void addA (const int& i) { A a(i); vA.push_back(a); }
// void addB (const string& s) { B b(s); vB.push_back(b); }
void addA (const A& a) { vA.push_back(a); }
void addB (const B& b) { vB.push_back(b); }

// Methods to access information for A,B
int getAN (const int& idx) const { return vA.at(idx).getN(); }
string getBstr (const int& idx) const { return
vB.at(idx).getStr(); }
// ... some more info

// All other methods
// ...
private:
vector<AvA;
vector<BvB;
};

Then, you change your A and B classes to use them...

class A {
public:
A (IR_A * r, const int& i) : rp(r), N(i) {}
int getN (void) const { return N; }
void fA (const int& idx)
{
// Access an A object at index idx through rp
}
private:
IR_A * rp;
int N;
};

class B {
public:
B (IR_B* r, const string& s) : rp(r), str(s) {}
string getStr (void) const { return str; }
void fB1 (const int& idx)
{
// Access an A object at index idx through rp
}
void fB2 (const int& idx)
{
// Access a B object at index idx through rp
}
private:
IR_B * rp;
string str;
};

Main can stay the same. If you want a bit more added security, you can
make all the methods of R which participate in IR_A or IR_B private. Then
you can only access those methods through one of the two interfaces.

Hope that is of some help.

joe
Jul 17 '08 #2

P: n/a
I am suspecting a fundamental misunderstanding of the underlying
problem and the simplified case presented here is quite reflecting
that. Anyway, passing a subclass of R to A/B isn't going to be able to
do anything to make certain public methods of R to unavailable to A
and B. I can think of a few solutions based on similar design
patterns, obscurity through encapsulation (containment) or
polymorphically though levels of base classes preferably abstract
(like interfaces in java).
So using your own example, contain R in RCA or RCAB and provide them
to A or B respectively or create a (fully abstract) AR and ABR,
inherit R from them, that is AR->ABR->R, construct R but pass R as AR
or ABR to A or AB respectively.
In both of the above cases, have public only those methods that A or B
should see.

- Murali.

On Jul 17, 11:19*am, Joe Greer <jgr...@doubletake.comwrote:
fgh.vbn....@gmail.com wrote in news:e790868e-086d-4cb4-bb40-
2c0fbdde2...@w7g2000hsa.googlegroups.com:


Hi,
I'm not sure if i'm asking the question correctly but anyway here it
is.
Say I have 3 classes - class A, class B, class R.
1) A and B are the building blocks and R is like a repository that
stores objects of A and B.
2) A is at the lowest level and should "know about" only other As. B
should know only about As and other Bs.
3) R has 3 types of public methods - (i) methods to add A,B (ii)
methods to access A, B and (iii) all other methods.
For now I pass a pointer to R to both A and B so that they can access
information from R as required. However, this exposes all public
methods (ie., (i), (ii) and (iii)) of R to both A and B.
How do I change it so that A and B can only access methods of type
(ii)? (The rationale is that A/B will never add another A/B and they
shouldn't be doing anything else related to R). Is there a way to make
a subclass of R called Rsub and pass that pointer to A,B? Is that a
good way to do it?
I have included code below.
Thanks.
#include <iostream>
#include <vector>
using namespace std;
class A;
class B;
class R;
class A {
public:
* * A (R* r, const int& i) : rp(r), N(i) {}
* * int getN (void) const { return N; }
* * void fA (const int& idx)
* * * * {
* * * * * * // Access an A object at index idx through rp
* * * * }
private:
* * R* rp;
* * int N;
};
class B {
public:
* * B (R* r, const string& s) : rp(r), str(s) {}
* * string getStr (void) const { return str; }
* * void fB1 (const int& idx)
* * * * {
* * * * * * // Access an A object at index idx through rp
* * * * }
* * void fB2 (const int& idx)
* * * * {
* * * * * * // Access a B object at index idx through rp
* * * * }
private:
* * R* rp;
* * string str;
};
class R {
public:
* * // Methods to add A, B
// * * void addA (const int& i) { A a(i); vA.push_back(a); }
// * * void addB (const string& s) { B b(s); vB.push_back(b); }
* * void addA (const A& a) { vA.push_back(a); }
* * void addB (const B& b) { vB.push_back(b); }
* * // Methods to access information for A,B
* * int getAN * (const int& idx) const { return vA.at(idx).getN(); }
* * string getBstr (const int& idx) const { return
vB.at(idx).getStr(); }
* * // ... some more info
* * // All other methods
* * // ...
private:
* * vector<AvA;
* * vector<BvB;
};
int main() {
* * R rep;
* * A a1(&rep, 100);
* * A a2(&rep, 200);
* * rep.addA(a1);
* * rep.addA(a2);
* * cout << rep.getAN(0) << " and " << rep.getAN(1) << endl;
* * // a2.fA(0); // should return info about a1
* * B b1(&rep, "dog");
* * B b2(&rep, "cat");
* * rep.addB(b1);
* * rep.addB(b2);
* * cout << rep.getBstr(0) << " and " << rep.getBstr(1) << endl;
* * // b2.fB1(0); // should return info about a1
* * // b2.fB2(0); // should return info about b1
* * return 0;
}

Well, the first thing that comes to mind is to use interfaces.

class IR_A {
public:
* *virtual void addA(const A& a) = 0;
* *virtual int getAN(const int& idx) = 0;
* *virtual ~IR_A(){}

};

class IR_B {
public:
* *virtual void addB(const B& b) = 0;
* *virtual string getBstr(const int& idx) = 0;
* *virtual ~IR_B(){}

};

class R : public IR_A, public IR_B {
public:
* * // Methods to add A, B
// * * void addA (const int& i) { A a(i); vA.push_back(a); }
// * * void addB (const string& s) { B b(s); vB.push_back(b); }
* * *void addA (const A& a) { vA.push_back(a); }
* * *void addB (const B& b) { vB.push_back(b); }

* * *// Methods to access information for A,B
* * *int getAN * (const int& idx) const { return vA.at(idx).getN(); }
* * *string getBstr (const int& idx) const { return
*vB.at(idx).getStr(); }
* * *// ... some more info

* * *// All other methods
* * *// ...
*private:
* * *vector<AvA;
* * *vector<BvB;
*};

Then, you change your A and B classes to use them...

*class A {
*public:
* * *A (IR_A * r, const int& i) : rp(r), N(i) {}
* * *int getN (void) const { return N; }
* * *void fA (const int& idx)
* * * * *{
* * * * * * *// Access an A object at index idx through rp
* * * * *}
*private:
* * *IR_A * rp;
* * *int N;
*};

*class B {
*public:
* * *B (IR_B* r, const string& s) : rp(r), str(s) {}
* * *string getStr (void) const { return str; }
* * *void fB1 (const int& idx)
* * * * *{
* * * * * * *// Access an A object at index idx through rp
* * * * *}
* * *void fB2 (const int& idx)
* * * * *{
* * * * * * *// Access a B object at index idx through rp
* * * * *}
*private:
* * *IR_B * rp;
* * *string str;
*};

Main can stay the same. *If you want a bit more added security, you can
make all the methods of R which participate in IR_A or IR_B private. *Then
you can only access those methods through one of the two interfaces.

Hope that is of some help.

joe- Hide quoted text -

- Show quoted text -
Jul 17 '08 #3

This discussion thread is closed

Replies have been disabled for this discussion.