#include "opengui/gui.h"
#include <iostream>
namespace OpenGUI
{
class Container
{
public:
Container(int x = 0, int y = 0, int w = 0, int h = 0);
~Container();
Container &operator[] (int i);
Container &operator[] (std::string name);
private:
std::vector<Container *> containers;
std::map<std::string, int> names; // points to vector
};
}
namespace OpenGUI
{
class OpenGUI
{
public:
OpenGUI(int x, int y, int w, int h);
void initialise();
void initialise(int x, int y, int w, int h);
Container &get_container();
private:
Container *container;
};
}
namespace OpenGUI
{ ///////////////////////////////////////////////////////////////////////////////
OpenGUI::OpenGUI(int x, int y, int w, int h)
{
initialise(x, y, w, h);
}
void OpenGUI::initialise(int x, int y, int w, int h)
{
container = new Container(x, y, w, h);
}
///////////////////////////////////////////////////////////////////////////////
Container &OpenGUI::get_container()
{
std::cerr << "->" << container << "<-";
return *container;
}
///////////////////////////////////////////////////////////////////////////////
}
void main()
{
OpenGUI::OpenGUI gui(0, 0, 800, 600);
OpenGUI::Container main = gui.get_container(); // slow (copies value rather then address
std::cerr << "->" << &main << "<-";
main["window"].function(data, whatever);
}
C++, use references without copying
I have a class, called GUI, which dynamically allocates an Container object. Via a function I would then like to pass the pointer/reference to the Container object, so the user can fill it. I don't see how I can easily do this, mainly because I want the code the look best at the user end and don't want to copy data rather then pointers.
Code:
Outputs 2 different addresses ofcourse, since I copy the data to a new address.
What would be a good solution in this case? I can't seem to find any. Either I use pointers, which would make the code look awfull and more difficult to handle.
Is there a way to do this? Any ideas?
Thanks.
iam not sure if i understood your Problem correctly:
you do not want to copy by value in this line right?
It copies the values because main is an object (on the stack) and not a reference.
(the standard =operator copies by value just like the default copy
constructor)
This should work: (AFAIK)
you do not want to copy by value in this line right?
OpenGUI::Container main = gui.get_container(); // slow (copies value rather then address
It copies the values because main is an object (on the stack) and not a reference.
(the standard =operator copies by value just like the default copy
constructor)
This should work: (AFAIK)
OpenGUI::Container& main = gui.get_container();
get_container() could return via an output parameter rather than a return value, e.g
Alternatively, declare 'main' as a reference. (and maybe call it something other than main while you're at it)
e.g
The pointer method and the output parameter method have the advantage that you can test the validity of the return value for get_container and handle it nicely. For the return by reference method, you've got no option but to handle an exception.
Of course, in the code you've presented so far, it will never be NULL, but it's difficult to know how the code will be used in the future. And there are some cases where there really is an absolute need to be able to check that value.
bool get_container(Container& containerOut){ if(mContainer != NULL) { containerOut = mContainer; return true; } return false;}
Alternatively, declare 'main' as a reference. (and maybe call it something other than main while you're at it)
e.g
void main(){ OpenGUI::OpenGUI gui(0, 0, 800, 600) OpenGUI::Container& guiMain = gui.get_container(); // blah}
The pointer method and the output parameter method have the advantage that you can test the validity of the return value for get_container and handle it nicely. For the return by reference method, you've got no option but to handle an exception.
Of course, in the code you've presented so far, it will never be NULL, but it's difficult to know how the code will be used in the future. And there are some cases where there really is an absolute need to be able to check that value.
Quote:Original post by Sandman
get_container() could return via an output parameter rather than a return value, e.g
*** Source Snippet Removed ***
Huh? That would create a copy as well. You cannot change the destination of a reference once created.
I think Noobico has pinpointed exactly what the original poster's mistake was.
-Markus-
Quote:Original post by Noobico
This should work: (AFAIK)
*** Source Snippet Removed ***
That works, thanks :).
Quote:And there are some cases where there really is an absolute need to be able to check that value.
I would like my library to be as usefull as possible, could you give me an example of such situation? I don't fully understand it.
I try to keep all dynamic allocations and pointer handlings transparant to the user. This keeps the user code clean and easy :)
Thanks guys.
Quote:Original post by Cygon
Huh? That would create a copy as well. You cannot change the destination of a reference once created.
Erk, of course you're right. I don't know what I was thinking. I blame too many late nights of C# coding.
Quote:
I would like my library to be as usefull as possible, could you give me an example of such situation? I don't fully understand it.
Basically, anywhere where you're returning something that might legitimately be NULL.
For example, suppose you wanted to defer allocation of the container to some later time, and remove the initialize call from the constructor. Suddenly it becomes possible to call get_container() without having allocated one.
If you're returning a reference, you'll get thrown an exception. In some cases, this may be what you want, but there are plenty of cases where it might be a bit drastic. Throwing exceptions inside destructors is never a good idea, for example.
If you return a pointer, you can check it for null without invoking the whole exception handling stack unwinding process.
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement