What's the best way to access the internal data structure within a class? - c++

I have a class A consisting of a bunch of internal data structures (e.g. m_data) and a few objects (e.g. ClassB):
class A
{
public:
...
private:
int m_data[255];
ClassB B[5];
}
What's the best way for B to access m_data? I don't want to pass m_data into B's function..
// updated:
Many thanks for the responses. Let me provide more contextual info.
I am working on an AI project, where I got some data (e.g. m_data[i]) at each time step. The class A needs to buffer these information (m_data) and uses a list of B's (example updated) to make inference. Class B itself is actually a base class, where different children derive from it for different purpose so I guess in this context, making B a subclass of A might not be clean (?)..

friend class ClassB;
Put this line anywhere in A's declaration if you want ClassB to access all of A's protected and private members.

One of:
Make ClassB a friend of A
Make A a sub-class of ClassB and make m_data protected rather than private
[In response to Mark B's comment]
If ever you feel the need to resort to a friend relationship, the design should be reconsidered - it may not be appropriate. Sub-classing may or may not make sense; you have to ask yourself "Is class A and kind of class ClassB?" If the question makes no sense intuitively, or the answer is just no, then it may be an inappropriate solution.

Ideally, you don't allow external access the data structure at all. You should rethink your approach, considering more the question "What are the functional requirements / use cases needed for ClassB to access instances of A" rather than offloading the management of the internal members to methods not managed within class A. You will find that restricting management of internal members to the class owning those members will yield cleaner code which is more easily debugged.
However, if for some reason this is not practical for your situation there are a couple possibilities that come to mind:
You can provide simple get/set accessor methods which, depending upon
your requirements, can be used to access either a copy of or a
reference to m_data. This has the disadvantage of allowing everybody
access, but does so only through well defined interfaces (which can
be monitored as needed).
ggPeti mentions use of friend, which may work for you, but it gives ClassB access to all of the internals of A.

A getData() function that returns m_data.
Use setData() to change the value.
So in the function in class B you would create a pointer to the class type A variable that you created. Lets just call this pointer 'p'.
Just do p->getData(), p.getData() may be the answer. I think they do the same thing but c++ uses the '->' and some other languages use the '.'. Don't quote me on that one though.
Good luck, sir. Hope I helped ya.

What's the best way for B to access m_data?
Depends on the use.
This is how would I do it :
class ClassB
{
// ...
void foo( A &a )
{
// use a's data
}
};
class A
{
//...
int m_data[255];
ClassB & B;
};
Depending on the implementation, maybe ClassB is not needed at all. Maybe it's methods can be converted to functions.

Related

How can I use a private member variable in a non-member function, when the variable happens to be a pointer?

Essentially my problem is that a function in a library I'm using, (function Foo in this code), requires a pointer to an object (Object* mbar) as a parameter. However, mbar is a private member variable to bar.
Normally, I'd just use a getter and pass by value, but if I pass the pointer, that would give direct access to the resource, which would break encapsulation. Any code could just call the getter and get free reign to modify it.
The next thing I thought was that I could use const pointers because they disallow modifying the resourse they point to, but as far as I could tell, I'd need to modify Foo to accept it, which is impossible as it's a library function.
The final thing I can think of is simply using a friend of Bar to call FoobarFunction, but I've always been told that friend functions are a last resort.
Is there a way to do this without breaking encapsulation in some way?
//Main.cpp
#include "Foobar.h"
int main()
{
Foobar fb;
Bar b;
fb.FoobarFunction(b);
return 0;
}
//Bar.h
#include "Object.h"
class Bar
{
private:
Object* mbar;
};
//Foobar.h
#include "Foo.h"
#include "Bar.h"
class Foobar
{
public:
void FoobarFunction(Bar bar)
{
Foo(bar.mbar);
}
};
The Easy Way Out
You can make the pointer const and then cast it when you pass it to the library function
Foo(const_cast<Object *>(bar.mbar));
This will work if Foo does not try to modify mbar. The cast removes the constness "in name only." Attempting to modify a secretly-const value can lead to Terrible Things.
But Really...
Even if there was a way to make Bar return a "read-only" pointer, the code sample in your question would still violate encapsulation. This particular flavor of non-encapsulation is called feature envy: the data lives in one object, but another object is doing most of the data manipulation. A more object-oriented approach would be to move the manipulation and the data into the same object.
Obviously, the sample code you've given us is much less complicated than your actual project, so I can't know the most sensible way to restructure your code. Here are a couple of suggestions:
Move the FoobarFunction into Bar:
class Bar
{
private:
Object* mbar;
public:
void FoobarFunction()
{
Foo(mbar);
}
};
Use dependency injection. Initialize mbar before creating Bar, then pass mbar into Bar's constructor.
int main()
{
Object *mbar;
Foobar fb;
Bar b(mbar);
fb.FoobarFunction(mbar);
return 0;
}
In this example, Bar is no longer the "owner" of mbar. The main method creates mbar directly and then passes it to whoever needs it.
At first glance, this example appears to break the guideline I mentioned earlier (the data and behavior are stored in different objects). However, there is a big difference between the above and creating a getter on Bar. If Bar has a getMBar() method, then anybody in the world can come along and grab mbar and use it for whatever evil purposes they wish. But in the above example, the owner of mbar (main) has complete control over when to give its data to another object/function.
Most object-oriented languages besides C++ don't have a "friend" construct. Based on my own experience, dependency injection is a better way of solving many of the problems that friends were designed to solve.
If the member is private, it's probably private for a reason...
If Bar has to be the only owner of Obj, then it should not expose it, as any other change to Obj might cause Bar to act incorrectly.
Although, if Bar does not have to be the only owner of Obj, you can either put a getter use dependency injection and pass it into Bar from outside, this way you can later pass it to foo as well.
A solution i think you should avoid is putting a call to foo inside Bar. This might violate the Single Responsibility Principle
I bealive that in this case tough, you can use a friend method.
I will refer you to a FAQ claiming that friend is not allways bad for encapsulation.
No! If they're used properly, they enhance encapsulation.
You often need to split a class in half when the two halves will have different numbers of instances or different lifetimes. In these cases, the two halves usually need direct access to each other (the two halves used to be in the same class, so you haven't increased the amount of code that needs direct access to a data structure; you've simply reshuffled the code into two classes instead of one). The safest way to implement this is to make the two halves friends of each other.
If you use friends like just described, you'll keep private things private. People who don't understand this often make naive efforts to avoid using friendship in situations like the above, and often they actually destroy encapsulation. They either use public data (grotesque!), or they make the data accessible between the halves via public get() and set() member functions. Having a public get() and set() member function for a private datum is OK only when the private datum "makes sense" from outside the class (from a user's perspective). In many cases, these get()/set() member functions are almost as bad as public data: they hide (only) the name of the private datum, but they don't hide the existence of the private datum.
Similarly, if you use friend functions as a syntactic variant of a class's public access functions, they don't violate encapsulation any more than a member function violates encapsulation. In other words, a class's friends don't violate the encapsulation barrier: along with the class's member functions, they are the encapsulation barrier.
(Many people think of a friend function as something outside the class. Instead, try thinking of a friend function as part of the class's public interface. A friend function in the class declaration doesn't violate encapsulation any more than a public member function violates encapsulation: both have exactly the same authority with respect to accessing the class's non-public parts.)

Why define Parent class as friend class?

I am looking at other's code and find one part I can't understand.
class a {
public:
function xxx () {.....}
}
class b : public a {
public:
xxxx
protected:
constructor()....
friend class a ; <= here why it is needed ????
}
As I understand, since b had already inherited from a, it should be able to use the function of a directly. What's the purpose of this "friend" declaration used for?
The friend allows a to use b's methods, not the other way around, which isn't implicit.
The design looks fishy though, a base class shouldn't care about derived classes.
friend class a; grants class a the right to access non-public members of b. So in this small example, an instance of a can call b::constructor(). Without friendship, it wouldn't be possible.
As to why, there is not enough information to answer that, other than there must be a need for instances of a to call b::constructor() (assuming that to be anything other than the syntax error it currently is).
As I understand, since b had already inherited from a, it should be able to use the function of a directly.
Yes. The friend specification though allows access the other way around (instances of a will be able to access private data and functions of b).
What's the purpose of this "friend" declaration used for?
The example above doesn't suggest any. The only situation where it may make sense is with using CRTP in certain situations (i.e. a is a template of b) but even so, if you see such a requirement ("must add friend declaration in b") it is possible that the design you're looking at is flawed.
Can you post a concrete example?
Depending on your projects/requirements, your class designs change. I have no comment on your class hierarchy but true your question is all about theories of friend usage. If you don't use friend, you will not be able to call B members from A. It is there for...cross-mating :D
It almost certainly means that there is a serious design problem. One of the basic rules of thumb for inheritance is that base classes should not need any information about derived classes. Making a a friend of b makes it possible for member functions of a to get at the internals of b objects.

C++ inheritance pattern

I am after your opinion on how best to implement an inheritance pattern in C++. I have two base classes, say
class fooBase{
protected:
barBase* b;
};
class barBase{};
where fooBase has a barBase. I intend to put these classes in a library, so that wherever I have a fooBase it can use its barBase member.
I now intend to create a specialisation of these in a specific program
class fooSpec : public fooBase{};
class barSpec : public barBase{};
Now I want fooSpec::b to point to a barSpec instead of a barBase. I know that I can just initialise b with a new barSpec, but this would require me to cast the pointer to a barSpec whenever I wanted to use specific functions in the specialisation wouldn't it?
Is there another way that this is often acheived?
Cheers.
Create a method in your specclass to cast the b into the special version.
That way instead of casting it all the time, it looks like a getter.
On the other hand OO is about programming towards interfaces and not objects. So what you are doing here looks like programming towards objects. But the is difficult to see as this example is purely theoretical.
You may consider the template solution:
template <class T>
class fooBase{
protected:
T* b;
};
and then use it as
class fooSpec : public fooBase<barSpec>{};
while ordinarily, the base would be used as fooBase<barBase>.
Is this what you want?
Normally we create a function that has the cast and returns the pointer -- and use that instead of the member directly.
Now I want fooSpec::b to point to a barSpec instead of a barBase.
There's no such thing as fooSpec::b. b belongs to fooBase, and your new class fooSpec is a (specialization of) a fooBase. You can't change the fact that b, a fooBase member, is of type barBase. This is a property of all the instances of fooBase that you can't invalidate in the particular subset of instances concerned by your specialization.
I know that I can just initialise b with a new barSpec, but this would
require me to cast the pointer to a barSpec whenever I wanted to use
specific functions in the specialisation wouldn't it?
Yes and no. Yes, you need to do that cast; but no, you don't need to do it every time. You can encapsulated in a function of fooSpec.
Is there another way that this is often acheived?
Not that I'm aware of.
this would require me to cast the pointer to a barSpec whenever I wanted to use specific functions in the specialisation wouldn't it?
That depends on whether the method you are trying to invoke is defined in the superclass and whether it is virtual.
You need to cast the pointer before invoking a method if one of the following is true...
The method belongs to the subclass only
The superclass has an implementation of the method and the subclass's implementation does not override the implementation in the superclass. This amounts to a question of whether the function is a virtual function.
Avoid data members in non-leaf classes, use pure virtual getters instead. If you follow this simple rule, your problem solves itself automatically.
This also makes most non-leaf classes automatically abstract, which may seem like an undue burden at first, but you get used to it and eventually realize it's a Good Thing.
Like most rules, this one is not absolute and needs to be broken now and then, but in general it's a good rule to follow. Give it a try.
If it looks too extreme, you may try one of the design patterns that deal with dual hierarchies such as Stairway to Heaven.

Instance-level encapsulation with C++

I have a two-part question. First, I understand that C++ provides only class-level data encapsulation, meaning that all objects of the same class have access to one another's private members. I understand the reason for this, but have found some links (i.e. http://www.programmerinterview.com/index.php/c-cplusplus/whats-the-difference-between-a-class-variable-and-an-instance-variable/) which appear to contradict this point, suggesting that I could do the following:
class testclass {
private:
// Below would be an instance-level variable, and new memory for it is set aside
// in each object I create of class testclass
int x;
// Below would be a class-level variable, memory is set aside only once no matter
// how many objects of the same class
static int y;
}
What I would like to do is actually make this work, i.e., I would like to define a variable in a class which is private in each instantiation (this is my second question). Since the code snippet above does not appear to achieve this, is there a work around I can use to create data that is private to individual objects? Thank you!
EDIT:
It's true that I'm still learning OO basics. I'll use the ubiquitous car example to show what I'm trying to do, which I'm sure must be a common thing to try. I'd welcome any suggestions for how to rethink it:
class car {
private:
int mileage;
public:
car(int); // Constructor
void odometer();
};
car::car(int m) {
mileage = m;
}
void car::odometer() {
return mileage;
}
int main(void) {
car ford(10000), honda(20000);
cout<<ford.odometer(); //Returns 20000, since honda constructor overwrites private variable 'mileage'
}
Is there any way to get the odometer() method to return the mileage of either the ford or honda, depending on what I want?
Priviledge (public, private, protected) only applies to names. Only during the time when a name is resolved will the compiler apply permissions. Once compiled, all such information is gone.
In your example above, all uses of the names x and y within a scope that resolves to THOSE variables will be private to your class. Only functions declared in your class, be they static or not, will be able to access those variables by name.
All bets are off however if you give out the variable to other objects that can then refer to the variable by other names which have other permissions.
I'm not sure what you're asking with reference to "in each instantiation". AFAIK, there is no native way to make a variable private such that only that instance can access it. In all cases, instances can access each other's private parts.
There's some ways you could get around this I suppose. First is to templatize your class and give each instance a different type. You could do this with an integer template parameter or something. This could make life annoying though as you try to work with these types as the same kind of thing. You'd have to virtualize and have an abstract base class or something.
Currently that's the only method I can think of. All others depend on calling entities playing nice.
Generally speaking it's rare that you'd want to protect members from other instances. The usual case of the same type being passed to the same type is during copy and assignment, where you basically need all knowledge about the source to correctly copy. My bet is that you need to rethink what you're trying to do, whatever that is.

C++ : restrict access to the superclass' methods selectively?

This is an interview question. I am not a C++ expert yet so i need some help in finding the answer to this question ( i first want to understand the question...is it a valid question?)
Question:
Suppose I have a class B that derives
from class A and I wanted to reuse
some, but not all of the methods of A.
How would I restrict access to the
superclass' methods selectively?
thanks!
I assume that
you cannot change the definition of A
you want to select which methods from A should be accessible from a B object.
The using directive solves your problem. Example:
class A
{
public: // or protected for that matter
void foo();
void bar();
};
class B : private A // or protected, depending on whether
// you want subclasses of B to expose
// some methods from A themselves
{
public:
using A::foo;
};
makes foo usable from class B, but not bar. But as a caveat, note that using A::foo will expose all overloads of foo.
The answer they probably want to hear is that you can put the methods to be reused in the protected section of the base class, the methods which should not be visible to the derived classes should go into the private section.
However, taking a step back, you might be able to score extra points by pointing out that there might be better measures for reusing code, depending on what the functions do (such as using free functions which are not visible in a header file).