I have a method that needs to calculate results for two variables in a object, so I am using pointers to return the results. The problem occurs because the object properties are private and can only be accessed through a getter method. The code I have looks like this:
Class myObject;
//Some other operations on myObject
double firstPram = myObject.getFirstDouble();
double secondPram = myObject.getSecondDouble();
someFunction(&firstPram, &secondPram);
myObject.setFirstDouble(firstPram);
myObject.setSecondDouble(secondPram);
This works but doesn't seem like the most elegant or efficient solution. Doing something like
someFunction(&myObject.getFirstDouble(), &myObject.getSecondDouble());
doesn't work and I get why. I just want to know if there is a way to access a varible through a method with a pointer.
It looks like someFunction should be a member of Class, because it reads and writes private variable. It can still reuse the standalone someFunction. E.g.:
void someFunction(double*, double*);
class Class {
double first_, second_;
public:
void someFunction() {
::someFunction(&first_, &second_);
}
};
The problem is "do you really want that an external object edits directly a private variable?". Probably not: you declared it private, so you should edit that through public method in that class. A good way is to pass the entire object to someFunction that edit the variables with getter and setter methods.
The second snippet will work if you change function getFirstDouble to return reference:
double& getFirstDouble()
of course it will break encapsulation even more than your current getters and setters.
How about having the function someFunction() within your class?
Let that function manipulate the object's variables.
So by calling myObject.someFunction(), you can do your necessary functionality. Also you don't have to expose the variables by getters and setters too.
Related
I encountered an issue while trying to do something in the process of learning C++ and I am not sure how to handle the situation:
class Command
{
public:
const char * Name;
uint32 Permission;
bool (*Handler)(EmpH*, const char* args); // I do not want to change this by adding more arguments
};
class MyClass : public CommandScript
{
public:
MyClass() : CommandScript("listscript") { }
bool isActive = false;
Command* GetCommands() const
{
static Command commandtable[] =
{
{ "showlist", 3, &DoShowlistCommand } // Maybe handle that differently to fix the problem I've mentioned below?
};
return commandtable;
}
static bool DoShowlistCommand(EmpH * handler, const char * args)
{
// I need to use isActive here for IF statements but I cannot because
// DoShowlistCommand is static and isActive is not static.
// I cannot pass it as a parameter either because I do not want to
// change the structure of class Command at all
// Is there a way to do it?
}
};
Any help would be greatly appreciated! :)
// Is there a way to do it?
No.
Either pass it as parameter, make it static, or make DoShowlistCommand non-static.
There are two potential answers here:
1. about use of non static items in a static functions:
As said in our previous question/answer, this is not possible, unless you'd have in the static function a specific MyClass object (and use object.isActive). Unfortunately, you can't do this here :
your code comments clearly show that you can't add a MyClass parameter to the function call;
the existing parameters don't suggest that you have already a pointer to parent class object;
it would not be adivsable to use global objects in such a context.
2. about what your're trying to do:
It seems that you want to have the function static, because you want to provide it in a table that maps script-commands to function pointers.
Alternative A
If all the function pointers used in commandtable are members of MyClass, you could think of using a pointer to a member function instead of a pointer to a function. The outside object/function that sets isActive on an object, could then refer the pointer to the member function, on the MyClass object it knows.
Alternative B
Revise the design of your code to implement your script engine by using the command design pattern: it's ideally suited for this kind of problems. It will require some refactoring of your code, but it will be so much more maintenable and extensible afterwards !
I don't think there is any way to do it. Here is why:
A static member function is not attached to any particular object, which means it cannot access other members that are not static, since they are attached to an object.
It doesn't look like you need to make it a static member. If you are sure you do - then pass it as a parameter. For example, make a
bool isActive();
function, and pass an argument from it to that function somewhere when you call this 'problematic' one.
You also could change your member variable to static, but it looks like you need it for EACH object, not one-for-all
I wrote a function to pass to a third party's class. A static function worked fine until the function needed access to a private member variable to do its work. I can do that using a lambda expression (given that it is converted to std::function either automatically or by casting).
Example:
void classA::doingThings()
{
...
classB::needsHelpToDoAThing(
[&](std::type foo) -> size_t { return myFunction(foo); }
);
...
}
size_t class::myFunction(type foo){
...
type someVar = m_somePrivateMember ...(some work)
...
}
But I don't really understand what I'm doing. Now this other class is using private member variables from a different class. Doesn't this violate encapsulation? Is this a hack or am I missing/misunderstanding a concept?
Encapsulation is the idea that other code doesn't get to poke around in your innards willy-nilly.
Here you created a helper function that can poke around in your innards. This helper function is part of your innards, even if you pass it to someone else.
This no more breaks encapsulation than a member method accessing private data. While it isn't part of the interface of the class explicitly, it is still part of the implementation.
I am trying to do something like this:
Create an object and bind its member functions to functions from a DLL. For example,
class A {
private:
int a;
public:
void func_a();
};
When loading from a DLL I want to create an A object, and set func_a to a function that is loaded from the DLL
A aObj;
(aObj.*func_a)() = getAdr(&s, h, "fmiGetTypesPlatform");
I do not know the syntax for it, but I mean I want to set the result of
getAdr(&s, h, "fmiGetTypesPlatform");
to an object's member function
Thanks in advance.
What you're looking for is a function pointer:
class A {
private:
int a;
public:
void (*func_a)();
};
Then, you can set this like any other pointer.
A aObj;
aObj.func_a = getAdr(&s, h, "fmiGetTypesPlatform");
Note that the referenced function, fmiGetTypesPlatform(), is a regular function. It is not a class method (i.e., no this, et al.), and it gets invoked via its function pointer.
(*aObj.func_a)();
If you know at compile time which DLL functions you want to use, you can make the class members one-line wrappers and encapsulate any data you need inside the object.
If you want to be able to assign arbitrary functions to class members, function pointers will work, with a little extra setup. Example code: http://goffconcepts.com/techarticles/calldll.html
Note that you can call a function pointer stored as a class member by name as if it were a function, with the usual object.func() syntax. In fact, this is how virtual member functions are implemented, under the hood.
If, however, the calls are not static, you still might want to put a wrapper around them so you can make the data they use private to your class.
I have a hooking library that i am porting to C++, the only problem i have its that i need a void pointer to client function, and i cant get a raw pointer of any function member, so for now it only works with static functions. This enforce me to make a singleton pattern which i dont want to.
Here is a snippet of the current problem i am facing for making an class that prints data regarding functions that are hooked:
class SpyLib
{
private:
HookLib hooklib;
std::vector<SpyRecord> records;
SpyRecord findRecord(int id);
public:
//Member function to callback after the hook
void spyer(void* register_context, int hookid);
};
Since i cant get the address of spyer function i need to declare it "static" that makes me declare the findRecord as well for finding data regarding the hook process. Since findRecord use "records" vector, that needs to be static too and so on. In the end i am dealing with a static class and forced to use a singleton pattern.
Question is: is there any method besides messing with vtables for finding the VA of a member function? if not, then how detour library from microsoft does it?.
Thanks.
You can always bypass the problem by delegating function call to wrapper non-member function:
class Pars
{
public:
SpyLib* spyLibPtr;
void* register_context;
int hookid;
};
void call_spyer(void* voidPtr)
{
Pars* parsPtr = reinterpret_cast<Pars*>(voidPtr);
parsPtr->spyLibPtr->spyer(parsPtr->register_context,parsPtr->hookid);
}
This way you can pass around pointer to call_spyer.
I have a C++ class like that:
class Example {
public:
int getSomeProperty(int id) const;
private:
lazilyLoadSomeData();
}
Basically getSomeProperty() return some data that has been loaded using lazilyLoadSomeData(). Since I don't want to load this data until needed, I'm calling this method within getSomeProperty()
int Example::getSomeProperty(int id) const {
lazilyLoadSomeData(); // Now the data is loaded
return loadedData[id];
}
This does not work since lazilyLoadSomeData() is not const. Even though it only changes mutable data members, the compiler won't allow it. The only two solutions I can think of are:
Load the data in the class constructor, however I do not want to do that, as lazily loading everything makes the application faster.
Make lazilyLoadSomeData() const. It would work since it only changes mutable members, but it just doesn't seem right since, from the name, the method is clearly loading something and is clearly making some changes.
Any suggestion on what would be the proper way to handle this, without having to cheat the compiler (or giving up on const-correctness altogether)?
You could make a proxy member object which you declare mutable and which encapsulates the lazy-loading policy. That proxy could itself be used from your const function. As a bonus you'll probably end up with some reusable code.
I would forward the call to a proxy object which is a mutable member of this class, something like this:
class Example {
public:
int getSomeProperty(int id) const
{
m_proxy.LazyLoad();
return m_proxy.getProperty(id);
}
private:
struct LazilyLoadableData
{
int GetProperty(int id) const;
void LazyLoad();
};
mutable LazilyLoadableData m_proxy;
};
Make lazilyLoadSomeData() const. It would work since it only changes mutable members, but it just doesn't seem right since, from the name, the method is clearly loading something and is clearly making some changes.
No, it's not making some changes, at least not from the viewpoint whoever called getSomeProperty. All changes, if you're doing it right, are purely internal, and not visible in any way from the outside. This is the solution I'd choose.