Currently I am working a lot with GUI design where I am using a lot of callback methods. In general those methods looks like: static void* Foo(void* data). Thanks to them I found out that I can access private variables without any issue just by passing their pointers.
Let say I have class like this:
class MyClass
{
public:
MyClass();
static void* Foo(void* data);
private:
int dummy_data = 3;
}
and methods:
MyClass::MyClass()
{
Foo((void*)&dummy_data);
}
void* MyClass::Foo(void* data)
{
received_value = (int*)data;
printf("Private value: %d\n",received_value);
}
And I can read dumy_data value. Normally if I would try to access this value compiler will rise error flag saying that this is private variable. And it doesn't matter if I'll pass it as a value, or pass pointer to my class and try to access this way.
So my question is - why is that happening? Yes, I know that I am passing pointer to value, but shouldn't compiler rise flag here as well?
The private and public sections control visibility of the names declared in those sections. They don't control visibility of the data. Outside code cannot refer to the MyClass::dummy_data name because it's private. If the class chooses to expose the value of that variable somehow, or even the address, then that's the class's choice, and any code with access to that other avenue (a pointer, in this case) is free to read it. There is no language error present, so the compiler doesn't complain.
It's valid.
Access restrictions are emplaced on the names of the members, not the members themselves. (Otherwise many getters would not work!)
A function that has been permitted (by being a member function) to access that member by name, has decided to pass along a pointer to that object. If you don't want that to happen, don't do it.
It would not actually be possible, in the general case, for the compiler to detect and block this code even if it were supposed to.
Related
I have a class "EngineObject"
I would like to have a custom function for that class which may vary by instance of that object.
Right now i'm doing it with function pointers like this:
class EngineObject{
public:
bool (*Update)(EngineObject* Me);
bool (*Prep)(EngineObject* Me);
bool (*OnCollide)(EngineObject* Me, EngineObject* Them);
};
As you may have noticed, this requires me to do something quite atrocious. I have to feed the object to its member function... Digusting
it also requires me to write extra getters and setters that I really don't want to be accessible from any other part of the code, just so I can see the "innards" of the EngineObject from functions passed in via function pointer
Is there some way I could write a function that I could apply, per instance of the object, that could access the privates of the object, and without having to pass the object to the function?
FOR CLARITY:
Let's say I want two EngineObjects
EngineObject1 = new EngineObject();
EngineObject2 = new EngineObject();
I'd like to set the update function of 1 to (something) and 2 to (something else)
EngineObject1.Update = &foo;
EngineObject2.Update = &bar;
I cannot simply use virtual functions and inheritance because these functions need to be able to be assigned and re-assigned at run-time.
The problem is that I need access to privates from these functions, and in order to do that i'd need to write public getters and setters for everything, which sort of erases the need for making anything private...
context:
The reason i'm doing this is to allow dynamic type generation at run time without introspection, to maximize what can be done from a scripting interface, and reduce the total number of functions that need to be bound to the scripting interface and reduce the learning curve for users.
Basically, you'd have an EngineObjectTemplate class which specified what all these functions would be for this dynamically generated type, and then the EngineObject would be created using a function in the EngineObjectTemplate class
EngineObjectTemplates may be generated at run time by combining various pre-written C++ functions (Update, Prep, OnCollide). This would be a "type" of sorts.
If a user wishes to write a new update, prep, or oncollide function, they could choose to write and compile it into a DLL file and add it to the project (Which my EXE will read and add to a list of function pointers, which can be referenced by string names in the scripting language to assign to templates and/or therefore engineobjects), or they could script it in the scripting language I choose, which would of course be slower.
Another reason why i'm doing it this way is that i'd like to avoid inheritance because it is HELL to make inherited classes work with the scripting wrapper I plan on using.
What you want to do is not possible because what you are actually asking is essentially:
"How can I make code living outside of a class access private members".
If this was possible without jumping through some ugly, ugly hoops, then it would mean that private is broken.
The only way to access private members of a class is that the class explicitly gives you access to them, either from its interface, or by marking the code as friend as part of its declaration.
Either the members are private, or they are not. You can't have it both ways.
N.B. This is a bit of a lie, as you can do some tricks in some exceptional corner-cases, but these should only be used as a last resort.
You can create a callable object class that overrides the () operator. A base class would provide the template for what the replaceable function receives as parameters with child classes implementing that particular method. Then you declare the callable class as a friend to your owning class. Like the following:
class EngineObject;
class Callable;
class EngineObject
{
private:
int member;
Callable *func;
public:
EngineObject(int m, Callable *f) : member(m), func(f) {}
int Call(int p)
{
return func(p);
}
friend Callable;
};
class Callable;
{
public:
int operator(EngineObject *eo, int param)
{
eo->member = param;
return param;
}
};
In the above, I also further hid the variable function call behind a wrapper so that an outside function doesn't need to pass the object as a parameter as well.
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.)
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.
I have a an instance of lasse1 and I want to use it in a method of lasse2 , this method is static method, this just doesn't work :
class Lasse2{
......
public :
static void function(void);
Lasse1* obj;
........
};
And now i want to use it like :
void Lasse2::function(void){
obj->dosmt(); // this doesn't work
.........
any idea how can I solve this?
If you want to access an instance member of your class, then you must have an instance of that class. There's no way around this. Your options are:
Make obj a static member. Do this if you intend to have a single obj for all instances of this class.
Remove static from function() so it becomes an instance method.
If you can't do either of those, then you need to find a way to pass an instance pointer to your function. For example, APIs that require a function pointer often have a mechanism for passing pointer-sized data to that function when it's eventually called.
Change your static method to explicitly pass the object pointer:
static void function(Lasse1* obj)
{
obj->dosmt();
}
But before you do, consider what you're really trying to do (and even write another question if you like).
You need an instance of your class to pull that off.
Create one or receive it through other means (function argument, global variable, class static variable, etc)
SLaks said it best: "You can't"
Here's why:
When you declare a member variable (not static, see obj above), you're telling the compiler that each object of type Lassie2 contains a pointer to a Lassie1.
When you declare a method static, that means that it is independent of all the instances (the actual objects) of that class. It doesn't operate on an object.
So inside of Lasse2::function, there's no this, no Lassie2 object for you to get the obj pointer from.
Structure's member are public by default ans class's members are private by default. We can access private data members through a proper channel (using member function). If we have access to member functions we can read/write data in private data member, so how it is secure...we are accessing it and we are changing data too.....
Access specifiers, such as private and public have nothing to do with security. In C++, for example, these specifications get compiled away and don't even exist in the compiled binary.
Rather, access specifiers are designed to make types easy to use correctly, and difficult to use incorrectly.
There are only two syntactic differences between class and struct:
In a class, members and base classes are by default private, whereas in a struct, they are public by default.
For historical reasons, class can be used instead of typename to declare a template type parameter.
In fact, there's no difference between
struct X {
void f() {}
private:
int i;
};
and
class Y {
int i;
public:
void f() {}
};
The only way that a class is more "secure" than a struct is that it gently "presses" you towards better encapsulation by defaulting to private members.
There really was no need to introduce a new keyword class, Stroustrup himself said that on a few occasions. (Read his book The Design and Evolution of C++ if you're interested in such things.) Basically, class was introduced to emphasize the fact that a struct with member functions isn't really a "structure" anymore in the way the term was used in C: a collection of loosely coupled objects of built-in types. It's a "class" in the sense the term is used in statically typed object-oriented languages, even though syntactically, it's no real difference from a struct.
primarily because the member functions can validate the values before storing them. eg say you have a field called 'age', which must be between 0 and 150. in a structure (or a class with a public field), you could just do obj.age = 200. whereas if you only had a setAge(int) method, that method could sanity check the value is between 0 and 150 before storing, possibly throwing an exception if necessary or just clamping the value if not.
the public/private/protected keywords are not meant for security but rather for encapsulation. you design your class by separating the implementation (where the private/protected members are used - those actually used to implement the functionality) from the interface (where you expose the public members - which users of the class -other objects- will access/call) and thus you are later able to change the private parts without changing the interface. the outside objects only need to know about the public members and use these safely regardless of the implementation.
if you are speaking about security, think that anyone could change the private members of your class if they really wanted to and knew the internal structure of the class , just by overwriting the appropriate memory locations with new values - but the problem here is not about security, it's at a lower level
Taking that classes and structs are exactly the same besides the default access, the question is how encapsulating the internal representation from the interface helps build more robust code.
The main difference is that you control when and how your class data is modified, and as such you can control your class invariants. Consider a simple vector class that has a pointer and a size. By having them private you can control how they change: if the resize method is called, both the pointer and the internal size variable will be coherently updated, keeping the invariant that accessing any position in the range [0..size) is well defined. If the member attributes were public, user code would update the storage or size without actually updating the other field, and that invariant could be broken.
Many classes have internal invariants for the correct usage. If you write a class that contains a string with user email addresses, by providing an accessor method you can control that the value passed in is a valid email address, while if the email field was public user code could reset it to anything...
The whole thing is that you control how your members are accessed and modified and that reduces the number of places where mistakes can be made and/or your chances of detecting it.