I have some code and data, both currently encapsulated within a struct, which in turn is within a namespace. I'm trying to integrate an external library, which makes use of old-fashioned callbacks. I need access to my data within the context of the callback, but the callback API provides no means of adding personalized parameters.
The only way I know to circumvent this is to either add a global pointer to my struct, so that the callback knows where to find the data, or use a tangle of boost classes to create a fake function pointer from my struct for the callback to use. Both options feel more like hacking around OOP limitations than actual solutions.
So, I'm debating whether or not to ditch the struct completely, and convert it to free-standing code and data. Essentially, the data would become global (or more likely, wrapped within a global struct), but would be within the confines of it's namespace.
Justification for making the data "global":
The code has a single purpose in the program, and always uses the same set of data for the life of the program. The data is never allocated or freed.
This code and data are never instanced. There never are and never will be multiple copies.
I have no love for OOP (I use C++ because it is the best tool for the job), so I don't feel the need to keep it encapsulated on principle alone.
However, there is one downside that I would like to avoid:
Even though the data is in a separate namespace (and ignoring the fact that I am the only person writing this program), there is nothing to prevent other parts of the program from accessing this data. And if it were to happen, I will have no easy way to track it.
The only idea I've had so far is to wrap the global data within an unnamed namespace. This should, for all intents and purposes, make it invisible to the rest of the code base, and remove the most common reason for not using globals. However, it also means that the code that does need to access it must all be contained within a single file, which could become a pain to work with if that file gets large.
Is there another option I'm not thinking of, or is this as good as it gets?
You could just some templated static functions to give you a data pointer, though you would have to specify these at compile time:
#include <iostream>
using namespace std;
template <class Data, int ID>
struct ext_library_context
{
static Data data;
static void callback()
{
// callback code, using data
cout << data << endl;
}
};
template <class Data, int ID>
Data ext_library_context<Data, ID>::data;
void ext_library_call(void callback())
{
callback();
}
int main()
{
int d1 = 1;
ext_library_context<int, 1>::data = d1;
int d2 = 2;
ext_library_context<int, 2>::data = d2;
ext_library_call(ext_library_context<int, 1>::callback);
ext_library_call(ext_library_context<int, 2>::callback);
}
As long as you use a unique Data/ID template parameter combination for each call, you shouldn't have any issues.
As for protecting your global state from unintended use, you could wrap it in a class, mark members as private to taste, and declare the callback functions as friends.
Put your data in a class and instantiate this class static-ally:
class MyClass {
private:
Data data; // variables which you avoid declaring globally
public:
void real_callback() {
do_something(data);
}
};
void callback() {
static MyClass my_class; // here is the trick.
my_class.real_callback();
// Or you can instantiate it on heap
// static auto my_class = new MyClass;
// my_class->real_callback();
}
int main() {
old_function_wanting_a_callback(callback);
}
Related
Say I have:
struct foo{
int bar;
int baz;
...
bool flag;
}
Can an access operator -> or . be overridden to detect if bar or any other member variable is modified ?
EDIT:
The purpose is if I have many member variables and any of them is changed, I have a quick way of setting a flag, instead of using setters to encapsulate all the variables, making the code verbose.
Your approach is flawed because even if you override access operators you will not catch pointers writing the actual memory.
If most of the variables have the same type you can use an enum for flags and a single function to set or get a specific variable.
For example:
private:
int bar;
int baz;
public:
enum IntVariables { varBar, varBaz };
bool flag;
void setVariable(int varId, int value) {
flag = true;
if (varId == varBar)
bar = value;
else if (varId == varBaz)
baz = value;
}
I considered the following approach:
Just use a wrapper class that can have any data type, but implement all operations. In this same wrapper class override operators, and use the wrapper class in other class that require any modifications of member variables to be detected.
template <class T>
class wrapper {
private:
T var;
... .. ...
public:
T doSomethingToVar(T arg);
... .. ...
//Wherever the variable is modified send out a notification to whomever needs to detect the changes.
};
Pros:
When declaring variables in whichever class needs to detect modification of variables, it is easy to declare using the wrapper, without much additional code.
To ensure modifications are detected, need to implement functions / getters / setters / overload operators to detect modifications. This is tricky, and requires some thought.
Cons:
Tricky to implement a general purpose wrapper that can detect all modifications, since complex types can have functions that modify themselves in ways one is not aware of.
Notes:
How to ensure that every method of a class calls some other method first?
This answer is a work in progress, and I think it may be useful to others and maybe just cool to know about eventually, so open to comments. Will keep updating.
Update:
While writing out the above answer, I considered a different approach, of shifting responsibility onto the member variable classes:
class DetectChanges{
void onDetectChanges(){
//This function should be called by all implementing classes when the class has changes.
}
Can make it a design choice that all member variables inherit from DetectChanges.
The above two approaches are what I'm considering now. Not a solution yet, but thought I would put it out for comments and see if eventually we can figure something out.
}
G'day,
Using C++, I would like to have a global object which contains several public member objects which can be accessed “through” the global object, while at the same time the code in the member objects should be able to call methods in the global object by accessing it as a global object (i.e. without passing a specific reference to the global object into the member objects).
I thought this would be quite straight forward, along the lines of my simplified example code below, but it won’t compile. Within the IDE, while viewing the header files I get “redefinition of GlobalObject / MemberObject” and "unknown type name" warnings (despite the “pragma once” in each header file ?). And when I compile the code the compiler reports “GlobalObject / MemberObject is undefined” errors.
I guess I have some sort of circular reference problem, though to be honest I don’t really understand why, as while the global object contains a reference to the member object(s), the member object(s) don’t contain a reference to the global object because I intend them to access the global object in the same way any other code would access it directly from the main function…? Doesn’t making GlobalObject global by declaring it outside of the main function then referencing it as external in the MemberObject header file do this, or am I mistaken here ?
I know people have strong opinions about the evil of global objects, but I believe there are circumstances where they are appropriate, especially in embedded systems with limited resources and which essentially “start-up” and never “shut-down” (or at least don’t shut-down in a controlled manner - the power just goes off). So I would like to know how what I am trying to do can be made to work, or if it can’t, I would like to understand why not.
I would appreciate any guidance anyone might like to offer, thank you.
GlobalObject.h
#pragma once
#include "MemberObject.h"
class GlobalObject
{
private:
int Data;
int Total;
public:
GlobalObject();
MemberObject MO;
int GetData(void);
void SetData(int NewData);
int GetTotal(void);
void SetTotal(int NewTotal);
};
GlobalObject.cpp
#include "GlobalObject.h"
GlobalObject::GlobalObject() : MO() { Data = 0; Total = 0; }
int GlobalObject::GetData(void) { return Data; }
void GlobalObject::SetData(int NewData) { Data = NewData; }
int GlobalObject::GetTotal(void) { return Total; }
void GlobalObject::SetTotal(int NewTotal) { Total = NewTotal; }
MemberObject.h
#pragma once
#include "GlobalObject.h"
extern GlobalObject GO;
class MemberObject
{
private:
int Data;
public:
MemberObject();
int GetData(void);
void SetData(int NewData);
void SetGlobalTotal(void);
};
MemberObject.cpp
#include "MemberObject.h"
MemberObject::MemberObject() { Data = 0; }
int MemberObject::GetData(void) { return Data; }
void MemberObject::SetData(int NewData) { Data = NewData; }
void MemberObject::SetGlobalTotal(void) { GO.SetTotal(GO.GetData() + Data); }
main.cpp
#include "GlobalObject.h"
GlobalObject GO;
int main(void)
{
GO.SetData(1000);
GO.MO.SetData(2000);
GO.MO.SetGlobalTotal();
}
This is something you should try to avoid when designing your classes.
If the global object is a singleton, one option is to have a global reference to that object, then everyone can go in via that reference. (This is somewhat common for things like logging frameworks, resource pools etc.) Trevor Hickey's answer uses this option.
The only other way is to have the sub-object know about the parent explicitly: the MemberObject constructor could accept a reference to a GlobalObject which is its parent. (Don't use a pointer as that will lead to Rule of Three issues)
What seems to be the issue?
struct Member{
void method(){}
};
struct Global{
Member member;
};
//global instance
Global global;
int main(){
global.member.method();
}
Using C++, I would like to have a global object which contains several public member objects which can be accessed “through” the global object, while at the same time the code in the member objects should be able to call methods in the global object by accessing it as a global object (i.e. without passing a specific reference to the global object into the member objects).
While you can do this, it points to a possible flaw in your design. Ideally, the member objects of the global object shouldn't rely on the global object to do their job. I would advise taking a step back and rethinking your design.
The simplest analogy I can give is that the nodes of a linked list don't rely on the linked list to be well defined and do their job. The link list, on the other hand, relies on the details of the node to do its job.
There's a feature called anonymous class in C++. It's similar with anonymous struct in C. I think this feature is invented because of some needs, but I can't figure out what that is.
Can I have some example which really needs anonymous class?
The feature is there because struct and class are the same thing - anything you can do with one, you can do with the other. It serves exactly the same purpose as an anonymous struct in C; when you want to group some stuff together and declare one or more instances of it, but don't need to refer to that type by name.
It's less commonly used in C++, partly because C++ designs tend to be more type-oriented, and partly because you can't declare constructors or destructors for anonymous classes.
It is not really needed in a strict sense and never was. I.e. you could always assign a name, for example anonymous1, anonymous2 etc. But keeping track of more names than necessary is always a hassle.
Where it is helpfull is at any place where one wants to group data without giving a name to that group. I could come up with a several examples:
class foo {
class {
public:
void validate( int x ) { m_x = x; }
bool valid() { return m_exists; }
private:
int m_x;
bool m_exists;
} maybe_x;
};
In this case the int and the bool logically belong together, so it makes sense to group them. However for this concrete example it probably makes sense to create an actual optional type or use one of the available ones, because this pattern is most likely used at other places as well. In other cases this pattern of grouping might be so special, that it deserves to stay in that class only.
I really do assume though, that anonymous classes are rarely used (I have only used them a couple of times in my live probably). Often when one want's to group data, this is not class or scope specific but also a grouping which also makes sense at other places.
Maybe it was sometimes helpful to make nested functions like:
void foo() {
class {
void operator()(){
}
} bar;
bar();
}
But now we have lambdas and anonymous classes are left only for compatibility reasons.
The use of anonymous classes is for preserving compatibility with existing C code.
Example:
In some C code, the use of typedef in conjunction with anonymous structures is prevalent.
There is an example of anonymous structs that can be used with Qt 5's Signal/Slot system with ANY class and without the QObject derivative requirement:
void WorkspaceWidget::wwShowEvent()
{
//Show event: query a reload of the saved state and geometry
gcmessage("wwShowEvent "+ this->title());
struct{void* t; void operator()(){ static_cast<WorkspaceWidget*>(t)->wwReloadWindowState(); }}f;
f.t=this;
QObject::connect( &reloadStateTimer, &QTimer::timeout, f);
reloadStateTimer.start();
}
void WorkspaceWidget::wwReloadWindowState()
{
gcmessage( dynamic_cast<QObject*>(this)->metaObject()->className());
}
Basically, I need to connect a timer signal to a non-QObject derived class, but want to pass mt "this" properly.
QObject::connect can be connected to ordinary function in Qt 5, so this anonymous class is actually a functor that keeps the this pointer in itself, still passing the slot connection.
Also you can do things with auto in anonymous (vs2015)
struct {
auto* operator->() {return this;}
//do other functions
} mystruct;
I have a function which aims to perform a recursive calculation. If my function is programmed recursively, it takes too long to compute. Therefore, I perform memoization by storing intermediate results in an array.
During the execution of my program, I might call the function with parameters (10,0),(5,5),(2,4) etc. Therefore I have a setup(double x) function which fills the entire array with the correct values. I can then access any of the array values without any further calculations. I only wait until x changes to call setup() again.
I am wondering how I can go about implementing this in c++. It doesn't make sense to me to use a class, as I would never need to create the associated object. I have implemented the functions fine in a namespace, but I'm still having a problem. Even If I use an unnamed namespace, the array used by my function is visible and can be modified from outside the namespace of the function. If I include the header file of the namespace, that is.
my code:
FunctionWrapper.h
namespace FunctionWrapper{
namespace{
double tempArray[10][10];
}
void setup(double x);
void getValues(int n);
}
Main.cpp
#include "FunctionWrapper.h"
int main(){
FunctionWrapper::tempArray[0][0] = 5; //Works
}
If you do not want tempArray to be nameable in other source files, don't declare it in the header file. Instead, declare it in an unnamed namespace in FunctionWrapper.cpp. Then, it can only be used directly from within that source file.
In general, a header file should not use an unnamed namespace, as it can (and often will) cause One Definition Rule violations.
Note that a better solution to your problem might, in fact, be to create a class that provides this functionality:
class ValueGetter
{
public:
ValueGetter(double x);
void GetValues(int n);
private:
double cache[10][10];
};
This way, you can create an instance of this type, and all of the state is owned by that instance. There are many benefits to avoiding global state, including increased maintainability and testability.
This does make sense as a class, and those functions as members of that class. Those functions act on that data, and you don't want anyone else to have access to that data, that sounds like a perfect use for a class. Why are you opposed to that?
Further to James's (as usual, excellent) answer, I'd structure things something like this:
namespace {
class value_cache {
double temp_array[10][10];
int x;
void setup(double x);
void internal_getValues(int); // same as your current GetValues
public:
void getValues(int n) {
if (x != n)
setup(x=n);
internal_getValues(n);
}
};
}
double function(int x, int y) {
static value_cache c;
c.getValues(x);
// probably more stuff here.
}
I see three options here:
Put the anonymous namespace in the .cpp file where your memoized function is implemented. It will then not be able to be access from anywhere else.
Make the array containing the memoized results a static variable inside the class.
Make a class that implements operator (), and use an instance of it as your 'function'. Then the memoization array can be a private member variable of that class.
Option 1 is the very simplist, and it will work. Of course, if your function is ever used in a multi-threaded environment you're going to have to think about inter-thread synchronization of access to the memoized value data structure.
Option 2 is a variant on option 1. Personally, I think it's the one you should go for. It has the exact same drawback though.
Option 3 is, IMHO, rather fiddly. In order to have something that looks and acts like your function you will have to declare a global variable of the class. But that's basically a singleton. And while that might be OK in this case, it may end up being a huge pain down the road.
There is one other option, but it's a huge amount of work. It's basically making a memoizing template. It would operate like option 3, but you could instantiate it for any function who's arguments satisfied the criteria for being keys of a hashmap.
I understand that one benefit of having static member functions is not having to initialize a class to use them. It seems to me that another advantage of them might be not having direct access to the class's not-static stuff.
For example a common practice is if you know that a function will have arguments that are not to be changed, to simply mark these constant. e.g.:
bool My_Class::do_stuff(const int not_to_be_changed_1,
std::vector<int> const * const not_to_be_changed_2)
{
//I can't change my int var, my vector pointer, or the ints inside it.
}
So is it valid to use static member functions to limit access. For example, lets say you have a function
void My_Class::print_error(const unsigned int error_no) {
switch (error_no) {
case 1:
std::cout << "Bad read on..." << std::endl;
break;
//...
default:
break;
}
}
Well here we're not going to be accessing any member variables of the class. So if I changed the function to:
static void My_Class::print_error(const unsigned int error_no) {
switch (error_no) {
case 1:
std::cout << "Bad read on..." << std::endl;
break;
//...
default:
break;
}
}
I'd now get an error, if I inadvertently tried to access one of my private var, etc. (unless I pass myself an instance of my class, which would be purposeful ^_^ !)
Is this a valid technique, similar to proactively making args that should not be changed constants?
What downsides might it have in terms of efficiency or use?
My chief reason for asking is that most of the "static" tutorials I read made no mention of using it in this way, so I was wondering if there was a good reason why not to, considering it seems like a useful tool.
Edit 1: A further logical justification of this use:
I have a function print_error,as outlined above. I could use a namespace:
namespace MY_SPACE {
static void print_error(...) {
...
}
class My_Class {
....
void a(void)
}
}
But this is a pain, because I now have to lengthen ALL of my var declarations, i.e.
MY_SPACE::My_Class class_1;
all to remove a function from my class, that essentially is a member of my class.
Of course there's multiple levels of access control for functions:
//can't change pointer to list directly
void My_Class::print_error(std::vector<int> const * error_code_list) {...}
//can't change pointer to list or list members directly
void My_Class::print_error(std::vector<int> const * const error_code_list) {...}
//can't change pointer to list or list members directly, access
//non-const member vars/functions
void My_Class::print_error(std::vector<int> const * const error_code_list) const {...}
//can't change pointer to list or list members directly, access
//non-static member vars/functions
static void My_Class::print_error(std::vector<int> const * const error_code_list) {...}
//can't change pointer to list or list members directly, access
//member vars/functions that are not BOTH static and const
static void My_Class::print_error(std::vector<int> const * const error_code_list) const {...}
Sure this is a bit atypical, but to lessening degrees so are using const functions and const variables. I've seen lots of examples where people could have used a const function, but didn't. Yet some people think its a good idea. I know a lot of beginning c++ programmers who wouldn't understand the implications of a const function or a static one. Likewise a lot would understand both.
So why are some people so adamantly against using this as an access control mechanism if the language/spec provides for it to be used as such, just as it does with const functions, etc.?
Any member function should have access to the other members of the object. Why are you trying to protect yourself from yourself?
Static members are generally used sparingly, factory methods for example. You'll be creating a situation that makes the next person to work with your code go "WTF???"
Don't do this. Using static as an access-control mechanism is a barbaric abomination.
One reason not to do this is because it's odd. Maintenance programmers will have a hard time understanding your code because it's so odd. Maintainable code is good code. Everybody gets const methods. Nobody gets static-as-const. The best documentation for your code is the code itself. Self-documenting code is a goal you should aspire to. Not so that you don't have to write comments, but so that they won't have to read them. Because you know they're not going to anyway.
Another reason not to do this is because you never know what the future will bring. Your print_error method above does not need to access the class' state -- now. But I can see how it one day might need to. Suppose your class is a wrapper around a UDP socket. Sometime in the middle of the session, the other end slams the door. You want to know why. The last messages you sent or received might hold a clue. Shouldn't you dump it? You need state for that.
A false reason to do this is because it provides member access control. Yes it does this, but there are already mechanisms for this. Suppose you're writing a function that you want to be sure doesn't change the state of the object. For instance, print_error shouldn't change any of the object's state. So make the method const:
class MyClass
{
public:
void print_error(const unsigned int error_no) const;
};
...
void MyClass::print_error(const unsigned int error_no) const
{
// do stuff
}
print_error is a const method, meaning effectively that the this pointer is const. You can't change any non-mutable members, and you can't call any non-const methods. Isn't this really what you want?
Static member functions should be used when they are relevant to the class but do not operate on an instance of the class.
Examples include a class of utility methods, all of which are static because you never need an actual instance of the utility class itself.
Another example is a class that uses static helper functions, and those functions are useful enough for other functions outside the class.
It is certainly fair to say that global scope functions, static member functions, and friend functions aren't quite orthogonal to one another. To a certain extent, this is largely because they are intended to have somewhat different semantic meaning to the programmer, even though they produce similar output.
In particular, the only difference between a static member method and a friend function is that the namespaces are different, the static member has a namespace of ::className::methodName and the friend function is just ::friendFunctionName. They both operate in the same way.
Well, actually there is one other difference, static methods can be accessed via pointer indirection, which can be useful in the case of polymorphic classes.
So the question is, does the function belong as "part" of the class? if so, use a static method. if not, put the method in the global scope, and make it a friend if it might need access to the private member variables (or don't if it doesn't)