Just faced with a situation and don't know what to do... Here is the code I have right now:
class IMyDbAccessor {
public:
int getSum(); // quite important for my case that it is not const.
// it does some caching. Of course I may use mutable,
// but actually it is not that important here.
};
void SomeBusinessLogic(IMyDbAccessor& dbacc) { /* implementation */ }
int main(int argc, char** argv) {
MyDbAccessor acc(argv);
SomeBusinessLogic(acc);
}
I don't like it, because it is not expressive enough. I would like to have
void SomeBusinessLogic(IMyDbAccessor&& dbacc) { /* implementation */ }
to show that SomeBusinessLogic wants to own a passed object, so main should look like
int main(int argc, char** argv) {
MyDbAccessor acc(argv);
SomeBusinessLogic(std::move(acc));
}
But of course it is impossible... Does anyone know what was a reasoning for that? For me it makes a perfect sense.
Or my feelings are wrong and I should not make SomeBusinessLogic responsible for IMyDbAccessor ownership, so it's better to pass it as a const IMyDbAccessor&?
I don't like it, because it is not expressive enough.
Looks plenty expressive to me. Passing an object by reference means the function can operate on an existing object provided by the caller, not on a copy. No worries about managing ownership.
I would like to have
void SomeBusinessLogic(IMyDbAccessor&& dbacc) { /* implementation */ }
to show that SomeBusinessLogic wants to own a passed object
That is not what an rvalue reference represents. An rvalue reference means that dbacc will refer to either a temporary object created by the compiler at the actual call site, or a pre-existing object that the caller passes with std::move(). Either way, the object that dbacc refers to is expected not to be used anymore after SomeBusinessLogic() exits, so SomeBuinessLogic() is allowed to "steal" ownership of any internal data held by the object that dbacc refers to, instead of make copies of it. This has nothing to do with ownership of the object itself. That still lies strictly with the caller.
so main should look like
int main(int argc, char** argv) {
MyDbAccessor acc(argv);
SomeBusinessLogic(std::move(acc));
}
But of course it is impossible...
What you are looking for is std::unique_ptr:
void SomeBusinessLogic(std:::unique_ptr<IMyDbAccessor> dbacc) { /* implementation */ }
int main(int argc, char** argv) {
std::unique_ptr<IMyDbAccessor> acc(new MyDbAccessor(argv));
SomeBusinessLogic(std::move(acc));
}
Or:
int main(int argc, char** argv) {
SomeBusinessLogic(std::make_unique<MyDbAccessor>(argv));
}
Only one std::unique_ptr at a time should ever hold a given pointer, as std::unique_ptr frees the memory being pointed at when destructed. That is what makes it "unique". When you see a std::unique_ptr, you know who the owner is. And passing a std::unique_ptr object by value to a function means it exists only for the lifetime of the function.
So, this approach makes it very clear that dbacc itself, not the caller, holds exclusive ownership of the IMyDbAccessor object, and will free that object when SomeBusinessLogic() exits (unless SomeBusinessLogic() decides to std::move() dbacc to another std::unique_ptr that is outside of SomeBusinessLogic()).
Or my feelings are wrong and I should not make SomeBusinessLogic responsible for IMyDbAccessor ownership, so it's better to pass it as a const IMyDbAccessor&?
I would, yes. Unless there is some compelling reason that SomeBusinessLogic() must take ownership away from the caller.
I think the type you are looking for is probably void SomeBusinessLogic(std::unique_ptr<IMyDbAccessor>)?
Indicates ownership is being transferred, and accepts derived objects
Do SomeBusinessLogic(std::forward(acc)).
For example:
#include <iostream>
#include <utility>
class IMyDbAccessor {
public:
virtual int getSum() = 0;
};
class MyDbAccessor : public IMyDbAccessor {
public:
virtual int getSum() { return 0; }
};
void SomeBusinessLogic(IMyDbAccessor&& dbacc) { std::cout << dbacc.getSum() << std::endl; }
int main(int argc, char** argv) {
MyDbAccessor acc;
SomeBusinessLogic(std::forward<MyDbAccessor>(acc));
}
Try it here:
http://cpp.sh/7pbrm
If you are looking for a way to give feedback "Hey I will modify this variable!" at the call location, I strongly recommend const pointers.
Then you have:
void SomeBusinessLogic(IMyDbAccessor* const dbacc) { /* implementation */ }
and
int main(int argc, char** argv) {
MyDbAccessor acc;
SomeBusinessLogic(&acc);
}
Related
Is it possible to get the command line arguments without receiving them via int main(int, char**)? I don't want to pass the arguments to multiple methods, so a global function would be perfect. Also, I do not want to store the arguments by myself via global variables. I'm running Windows and Linux.
edit:
Example:
int main()
{
int argc = GetArgumentCount();
char ** argv = GetArguments();
return 0;
}
edit:
It's possible to use LPTSTR WINAPI GetCommandLine(void); in win32.
https://msdn.microsoft.com/en-us/library/ms683156(v=vs.85).aspx
I'm looking for equivalent functions in Linux.
Is it possible to get the command line arguments without receiving
them via int main(int, char**)?
Yes, with platform-specific functions. But that's not necessary (see below).
I don't want to pass the arguments to multiple methods,
That's understandable. It's an anti-pattern also known as "tramp data".
Also, I do not want to store the arguments by myself via global variables.
Yes, global variables are rarely a good idea.
Here's an alternative approach: store them as a static local container object in some globally available non-member function which returns the container by reference.
Example:
#include <iostream>
#include <string>
#include <vector>
std::vector<std::string>& Arguments()
{
static std::vector<std::string> arguments;
return arguments;
}
void f()
{
// use arguments anywhere else:
std::cout << Arguments()[0];
}
int main(int argc, char* argv[])
{
for (int i = 0; i < argc; ++i)
{
Arguments().push_back(argv[i]);
}
f();
}
Of course, this can be made more sophisticated. For example, you might want to prevent anyone else but main from changing the vector by wrapping the vector in a class and declaring main as a friend, something like this:
#include <iostream>
#include <string>
#include <vector>
class Arguments final
{
public:
static int Count()
{
return arguments.size();
}
static std::string Get(int index)
{
return arguments[index];
};
private:
Arguments() = delete;
friend int main(int argc, char* argv[]);
static std::vector<std::string> arguments;
};
std::vector<std::string> Arguments::arguments;
void f()
{
// use Arguments anywhere else:
std::cout << Arguments::Get(0);
}
int main(int argc, char* argv[])
{
for (int i = 0; i < argc; ++i)
{
Arguments::arguments.push_back(argv[i]);
}
f();
}
Note that special care is needed to avoid bugs at program shutdown, when static objects are destroyed. You must make sure that no destructor of a static object accesses Arguments, or else you risk undefined behaviour.
Is it possible to get the command line arguments without receiving them via int main(int, char**) ?
No (at least, not in portable manner), however you could put the usual argc, argv into some global variable (or other global data, often after parsing). And that could also be into some static data with other functions in the same translation unit retrieving it. Hence a reasonable (readable and portable) approach would be:
static int myargc;
static char **myargv;
int GetArgumentCount(void) {
return myargc;
}
char**GetArguments(void) {
return myargv;
}
int main(int argc, char**argv) {
myargc= argc;
myargv= argv;
/// etc....
Notice that on some systems or some implementations you might access to the command line arguments in some other ways.
dirty Linux specific tricks
For example, on Linux, using proc(5), you might parse /proc/self/cmdline but it is unreasonable to do that (on your Linux system, try to run od -cx /proc/self/cmdline in your terminal to guess what I mean), so I still recommend using int main(int argc, char**argv) and storing, in some global or static data, the argc and argv, or more probably, do some parsing of program arguments.
So on Linux, you might code your GetArgumentCount and GetArguments functions (by parsing /proc/self/cmdline, see also this) but it would be foolish to do so without using argc and argv from main (even if it is technically doable). Coding such a crazy GetArgumentCount and GetArguments which parses /proc/self/cmdline is left as an exercise to the masochistic reader.
Perhaps you need that because some static data's constructor -running before main and called before it from crt0- uses them; but in that case, your program's design is IMHO very wrong. I have no idea if similar dirty tricks are doable in Windows.
If you really think that is a good idea, you can easily make cor command line arguments global:
int argc_ = 0;
char** argv_ = NULL;
int main(int argc, char* argv[]) {
argc_ = argc;
argv_ = argv;
// ...
}
See my code below:
class A
{
public:
A()
{
i = 0;
if(pt != NULL)
{
std::cout << "why" << std::endl;
}
}
A(bool flag)
{
i = 0;
pt = new B(3.14);
}
private:
class B
{
public:
B(double in) : j(in) {}
private:
double j;
};
private:
int i;
B *pt;
};
int main(int argc, char *argv[])
{
A obj; // place1
int *p;
if(p != NULL)
{
std::cout << "test2" << std::endl;
}
return 0;
}
In this piece of code, I wonder to know if pt will be initialized #place1.
The other question is that if I delete the definition of obj, test2 will print, if not, then why?
Value of p is undefined. It may be 0 or 1 or 2 or ......
So if it is your lucky day, you may get a print otherwise not.
Moral: Don't rely on what you get, initialize variables by yourself.
In this piece of code, I wonder to know if pt will be initialized #place1.
It is not initialized to anything. Technically, it is default-initialized, which for a pointer means no initialization is performed. This means it can hold any value, and it is undefined behaviour to read from it.
In C++11, if you hav value-initialized obj, then pt would be zero-initialized:
A obj{}; // obj.pt is nullptr
The other question is that if I delete the definition of obj, test2 will print, otherwise not, why?
p has an undetermined value too. It can be NULL, but it may not be. Reading from it is undefined behaviour too. So, it can take the value of NULL sometimes, sometimes not, and you cannot rely on and predictable behaviour.
According to the C++ Standard local variables are not initilized implicitly. So in this code snippet
int main(int argc, char *argv[])
{
// ...
int *p;
// ...
p is not initialized by the compiler implicitly because p is a local variable. It could be zero-initialized if p had static storage duration. For example
int *p;
int main(int argc, char *argv[])
{
// ...
In this code snippet variable p will be zero initialized.
As for the class A then in this code snippet
int main(int argc, char *argv[])
{
A obj; // place1
object obj will be default initialized that is the default constructor of the class will be called. As you do not initialize data member pt in the constructor its value will be undefined.
Again if the object had static storage duration then at first the memory occupied by the object would be zero-initialized before calling the default constructor. In this case pt would be zero-initialized
A obj;
int main(int argc, char *argv[])
{
Pointers are not initialized by default. You need to initialize it in your constructor (for members) or at the place of declaration (for local variables)
C++ will not initialize your instance variables for you. As long as you don't set them to a value, they will have a random value (or some value that looks like random garbage).
if(pt != NULL)
will be probably true since pt is not initialized to NULL in code it can be any value. pointer should be initialized to NULL in code by the programmer.
you can read this related question. to know about it.
In my class implementation, I have something like this:
base class
class swcWidget :
public swcRectangle
{
public:
swcWidget();
virtual ~swcWidget();
void update(float dt);
protected:
inline virtual void oPaintOnTop() { }
private:
};
derived class
class swcButton :
public swcWidget
,public swcText
{
public:
swcButton();
virtual ~swcButton();
static const int DEFAULT_SIZE = 20;
protected:
private:
void oPaintOnTop();
};
class swcApplication
{
public:
swcApplication(int argc, char *argv[]);
virtual ~swcApplication();
int run();
struct Controls
{
typedef std::vector<swcWidget*> vWidgets; //option 1
~Controls();
/////////////////////////////////
// M A I N P R O B L E M //
/////////////////////////////////
void add(swcWidget &&widgets); //most preferred option
//but gets demoted to base class.
void add(swcWidget *widgets); //second choice
//but should I make a copy of it?
//or just make a reference to it?
//and this one does what I wanted to.
//but still unsure on other things I don't know
void add(swcWidget *&&widgets); //this compiles fine (?)
//I don't know what kind of disaster I can make into this, but still does not do what I wanted.
inline vWidgets &getWidgets() {
return widgets;
}
private:
vWidgets widgets;
};
Controls controls;
};
I know some working option like this:
making the
swcApplication::Controls::widgets
as type of
std::vector<std::shared_ptr<swcWidget>>
but my code will bind into std::shared_ptr and I cannot make simple syntax like this:
swcButton btn;
app.controls.add(std::move(btn));
Example usage:
main.cpp
int main(int argc, char *argv[])
{
swcApplication app(argc, argv);
app.windows.create(640, 480);
if (font->load("fonts\\georgia.fnt") != BMfont_Status::BMF_NO_ERROR)
{
puts("failed to load \"georgia.fnt\"");
}
{
swcButton btn;
btn.setPosition(100, 100);
btn.setFont(font);
btn.text = "Ey!";
app.controls.add(std::move(&btn));
// btn.text = "Oy!";
}
return app.run();
}
Update:
Here's the temporary definition of swcApplication::Controls::add() although it may still vary
void swcApplication::Controls::add(swcWidget &&widget)
{
widgets.push_back(std::move(widget));
}
If a class is moveable, then it will in turn move it's members one by one. For this to be efficient, these members must either be small POD's or must be allocated on the heap. You must add this functionality, not forget to move any member, and object slicing is a concern to watch out for.
Given the class is non-trivial, you have the most efficient move construct available when you just use a pointer directly (at the cost of heap allocation time of course). No slicing is possible, and no member can be forgotten to be moved, since you move the whole object in one go. The one hurdle to watch out for is to keep track of who owns the pointers - you'd better set it in stone, but if that's done then there are no issues anymore.
The move semantics are wonderful, but if your classes are somewhat involved I think pointers in this case are easier / more efficient to work with. I'd thus stick with the pointer variant, and make sure your collection will own the pointers (and release them again via RAII) - make liberal use of comment in your public interface saying so. You can do this by storing some form of smart pointer (hint: be careful with unique_ptr's!), or (less safe) make and always use a Clear() member that delete's all pointers before clear()'ing the collection.
EDIT
Whet you define your widgets member to be of type vector, then example code could be:
To class swcApplication add:
void swcApplication::Controls::ClearWidgets() {
for (auto& nextWidget: widgets) {
delete nextWidget;
}
widgets.clear();
}
Don't forget to call ClearWidgets at the appropriate times (like in your destructor).
Adding widgets can be done with:
// Note: any passed widget will not be owned by you anymore!
template <typename Widget>
void swcApplication::Controls::add(Widget*& widget) {
widgets.push_back(widget);
widget = nullptr;
}
From now on you can add widgets like
swcButton* btn = new swcButton;
app.controls.add(btn);
// btn is now owned by app.controls, and should be set
// to nullptr for you to prevent misuse like deleting it
Using a smart pointer here should make it more safe, though storing unique_ptr's makes accessing them a bit error-prone (watch out for grabbing ownership back from the container when accessing them), and a shared_ptr gives overhead which might be unneeded here.
Lets consider the following code:
void main(int argc, char* argv[])
{
Foo foo;
//at this point I don't need foo any more
//a lot of stuff here
}
If I only need foo only for short amount of time,isn't it would be better to allocate it on a heap and delete before executing rest of the code?
No, it's better to write an inner scope.
int main()
{
{
Foo foo;
// use foo
}
// more code
}
But doing this should be a hint that it might be better to put foo in a completely separate function.
There's no reason to use heap allocation here though. That solution would be worse than the problem.
GLUT is a great API and it's very easy to use but I am having some difficulty with how it handles scope. When defining callbacks there is no option to pass parameters so it seems to me as though the programmer is forced to rely on global variables, which I find difficult to accept. Right now I have all the GLUT code in it's own module, running on it's own thread, and define a static pointer which I assign at the entry point to the module, like so:
Main module
int main( int argc, char** argv ) {
int foo;
boost::thread graphicsThread(glutMain, argc, argv, &foo);
//...
graphicsThread.join();
return 0;
}
GLUT module
static int* FOO_REF;
int glutMain( int argc, char** argv, int* foo ) {
FOO_REF = foo;
glutInit(&argc, argv);
//etc...
Is there a better solution than this?
If you're using freeglut or a derivative and willing to confine yourself to freeglut derivatives only it has a non-standard extension to solve exactly the problem. You can associate a void* with every window. If you make that a struct that contains all the per-window data you want you can avoid the globals entirely.
Synopsis:
#include <GL/glut.h>
#include <GL/freeglut_ext.h>
void * glutGetWindowData();
glutSetWindowData(void *data);
What I did was declare a global.h for all my globals. And initialize them in main. For my "basic/general" variables (ie camera, position, iterationNumber,...) they were all declared seperately. In main:
include "global.h"
Vector position_g = ...
Vector angles_g = ...
int time_g = 0;
int main () {
...
}
But for the variables that were "section specific" ie only in one game mode/level, I made a union and an enum.
enum mainGame{skipLevel, ...};
enum mainMenu {viewingSettings, ...};
typedef union generic_union {
int i;
char c;
bool b;
char s[100]; // or char * s;
float f;
} generic;
And declared a globalData variable.
extern generic * globalData; // in global.h
generic * globalData = NULL; // in main
Which can now be used:
int main () {
...
globalData = malloc (sizeof (generic)*numGlobals);
globalData[skipLevel].b = false;
...
}
Now when in your key press handling function, you can assign a key to toggle globalData[skipLevel]. And in any other file all you have to do is include global.h.
include "global.h"
void onKeyPress (... ) {
If (inMainGame) {
If (key == SPACE) {
globalData [skipLevel] = true;
}
}
And finally the use:
include "global.h"
void levelManager () {
...
if (globalData[skipLevel]) level++;
...
}
Pros
Only have to lug around 1 variable and one include.
You can free variables you no longer want or are using in that instance. (very useful for reducing "pollution"). If one game mode only needs 1 variable, thats all you have to store, if it needs 48, just as easy!
Can easily handle any variable type, by adding it to the union.
Totally Portable
Cons
Have to remember variable type to dereference the generic union (not that hard)
And watchout for enums being used (you can use a style for enums like mainMenu_e to solve this)
Adds complexity, but as the variable number grow, a system like this because well worth it.
Personally I find this very neat despite the few extra moving parts.
If this is unclear let me know, and Ill try to fix it :)