|
I have a constraint (due to gui stuff) that I want a dedicated "GUI" thread to make any gui calls. I essentially need to be able to send functions over from the "main" thread to the "GUI" thread for the "GUI" thread to call. These functions will have an arbitrary number of arguments, and will often have a return value that I'll want to use in the "main" thread. What I've done right now, is created a gui_call class, which has a virtual do_work() function. Any real gui_call I have inherits from this base class, and all the parameters are given to the class in the constructor. This is incredibly tedious, and there must be a better way. Often these gui_call's are just one function call (but sometimes they're more). Is boost::bind the correct way to do this instead of what I'm doing right now?
|
# ? Mar 9, 2011 21:27 |
|
|
# ? Jun 3, 2024 10:47 |
Hmm this is more of a design philosophy thing, but I think your approach sounds bad in some way. The way I view software, the user interface drives the program, so the user interface is always the "main" program. Examples: The user launches a GUI that creates some backend objects the GUI will then drive to let the user do work. The user enters a command on a commandline, the CLI frontend parses the commandline, creates the appropriate backend objects, and drives them to perform the work the user requested. A remote client makes a request to the server interface, which drives the backend to serve the request. What I want to say is, IMO you should not have the backend drive the UI, but the UI drive the backend. The backend should then have a notification interface where the UI can register to get updates on the work being performed. The result will be that the UI is aware of the backend and calls that directly, while the backend is only aware that someone has registered for change notifications. For those change notifications, boost::bind sounds like a good choice. (Remember to wrap some appropriate synchronisation mechanism around this.) On a side note, remember that it isn't uncommon for GUI libraries to require that all GUI code takes place in the main thread, i.e. the initial thread your main() function runs on. You're probably better off having a "main" thread that does GUI, and a "work" thread that does work. Of course this depends entirely on your platform, but if you're multi-platform you really want to have the main thread be the GUI thread.
|
|
# ? Mar 9, 2011 22:14 |
|
nielsm posted:As far as what the project I'm doing is. See this post: http://forums.somethingawful.com/showthread.php?threadid=2773485&pagenumber=207&perpage=40#post386889568 and the following posts. This is a library used to teach CS1 courses using robots. Many programs written will have no graphical windows at all, only a terminal window. The graphical windows only exist when the students (users) request them. Furthermore, this is a port of a python library, so I need to emulate the way the Python Library does its stuff.
|
# ? Mar 9, 2011 23:12 |
|
Is there an idiomatic workaround for the fact that you can't use remove_if on STL maps because you can't reorder them? (Or, if you can, how do you do it?)
|
# ? Mar 9, 2011 23:23 |
|
Harokey posted:I have a constraint (due to gui stuff) that I want a dedicated "GUI" thread to make any gui calls. I've asked myself this question before, since I always end up with a similar solution to you for cross thread communication stuff. I was just googling around about bind, when I came across this: http://www.codeproject.com/KB/library/BoostBindFunction.aspx From what I can tell, he seems to have created a sort of generic Command class and he uses bind to attach function calls to it with arbitrary numbers of parameters. He then builds a vector of these commands, all attached to different functions, which he then iterates through, executing each function in sequence. I haven't tested it out myself, but it certainly looks like it might help solve the problem.
|
# ? Mar 10, 2011 00:02 |
|
GrumpyDoctor posted:Is there an idiomatic workaround for the fact that you can't use remove_if on STL maps because you can't reorder them? (Or, if you can, how do you do it?) code:
|
# ? Mar 10, 2011 00:19 |
|
Okay, here's the deal. I'm in an introductory programming class (C++) that's mostly just a refresher from some intro classes I've taken years ago. However, now we're starting to work with strings, and that's somewhat new territory for me. And the instructor is terrible. I'm not asking for you to do my homework for me, but I could use a bit of help to come up with the right algorithm for this assignment. I feel like I'm close, but I must be missing something simple. The assignment is to take a line of input ending with a '.' and format it so it looks like a proper sentence. Capitalize the first letter, remove extra spaces between words, and make the other letters lowercase. I've got the case stuff down... that's easy, but I'm stuck on the space problem. My first approach was to just loop through the string and check the current index with the index next to it, and if they're both spaces, erase one of them: code:
I don't know if I'm just overthinking this or what, but I'm fairly stumped on which direction to go at this point. I've also thought about just removing all the spaces altogether and trying to mark the index of where they were so I could insert one after the fact, but I can't figure out how do accomplish that, either. Any suggestions? Again, not looking for an outright answer, just a point in the right direction.
|
# ? Mar 11, 2011 16:04 |
|
brc64 posted:Unfortunately, this method doesn't seem to work when there are more than two spaces. For example, the input "Testing one." end up comparing "g " and " o" in addition to " ", and an extra space is left in. At least, that seems to be the case, when I through some cout statements into the loop to try to help me debug. You also go one too far at the end of the loop, because you're looking at string[i+1] when i is the final character - not a big deal in this case since it'll just be a terminating null character, but a thing to be wary of in general.
|
# ? Mar 11, 2011 16:15 |
|
roomforthetuna posted:It's supposed to be testing "g " and " o", that's not your problem. The problem you have is that when you erase a space you still move your index up one, when you need to check the same position again. So I need to repeat my check any time I erase a character, before advancing the index. Oh! I think I know how to do that! Time to test! Thanks for the quick input!
|
# ? Mar 11, 2011 16:27 |
|
Or you need to change your loop to only increment the index when you don't erase a character.
|
# ? Mar 11, 2011 16:35 |
|
Jethro posted:Or you need to change your loop to only increment the index when you don't erase a character. Yeah, I think I've got it, but I can't get Visual C++ 2010 Express to compile even the same code that worked in Visual Studio 2008 in the school labs, so I guess I'm going to have to wait until I can get back to campus to test it out. Cheap community college doesn't even offer academic priced Microsoft software, or I'd probably just buy it.
|
# ? Mar 11, 2011 17:01 |
|
Also, just to catch this early in your learning, apparently it's better to get into the habit of "++i" rather than "i++" for various reasons. I habitually do i++ because I've already been doing it that way for years, but since you haven't, try to form the better habit!
|
# ? Mar 11, 2011 17:06 |
|
roomforthetuna posted:Also, just to catch this early in your learning, apparently it's better to get into the habit of "++i" rather than "i++" for various reasons. I habitually do i++ because I've already been doing it that way for years, but since you haven't, try to form the better habit! Despite not wanting to write code for a living, I do love the knowledge I get from these classes, and it's amazing just how much even entry level programming helps with being able to troubleshoot problems with other software. What I would love would be a class devoted entirely to advanced shell scripting... that's more up my alley. Introductory programming gives me a nice stepping stone into learning more of that on my own, at least.
|
# ? Mar 11, 2011 17:18 |
brc64 posted:I'm not asking for you to do my homework for me, but I could use a bit of help to come up with the right algorithm for this assignment. I feel like I'm close, but I must be missing something simple. The assignment is to take a line of input ending with a '.' and format it so it looks like a proper sentence. Capitalize the first letter, remove extra spaces between words, and make the other letters lowercase. I've got the case stuff down... that's easy, but I'm stuck on the space problem. Are you required to modify the string in-place? It might be easier to copy the source to a destination, one character at a time, and keep a bit of state. E.g. whether you are at the beginning of a sentence, whether the last copied character was a space. So sometimes you modify the character you copy, and sometimes you skip over a character without copying.
|
|
# ? Mar 11, 2011 18:14 |
|
roomforthetuna posted:Also, just to catch this early in your learning, apparently it's better to get into the habit of "++i" rather than "i++" for various reasons. I habitually do i++ because I've already been doing it that way for years, but since you haven't, try to form the better habit! Why is that? I always notice people tend to favor pre-incrementing, but I never really understood the logic as to why. Like you, I always use i++ unless I explicitly need to. I vaguely remember a friend who studied assembly code saying something about it being more efficient on some processors, but I kind of assumed that with modern optimizing compilers, it was irrelevant. Jethro posted:Or you need to change your loop to only increment the index when you don't erase a character. I think you could also fix the issue by running through the string backwards: code:
Gerblyn fucked around with this message at 21:09 on Mar 11, 2011 |
# ? Mar 11, 2011 21:02 |
|
It's irrelevant on any modern compiler if the operand is of primitive type. If it's of class type, then using post-increment causes an unnecessary copy of the object. If the class just wraps some primitive type, then again that's probably irrelevant; but in the (very rare) case of a heavyweight iterator with serious internal state, that can be a major expense. I think this point tends to be overblown, but I certainly sympathize with people who say it's just simpler to teach people to always favor pre-increment.
rjmccall fucked around with this message at 21:15 on Mar 11, 2011 |
# ? Mar 11, 2011 21:12 |
|
brc64 posted:
Just do it this way, easy as pie code:
|
# ? Mar 12, 2011 00:06 |
|
I'm using C++ and QT for a multithreaded application that I have developed. The second thread uses a bunch of DLLs for the stuff that it does. I've noticed that the second thread sometimes hijacks the working directory of the application to the location of the DLLs that it loads (so relative paths defined in my code and/or external configuration files no longer work). Is there a way to get around this? It seems very very random when it happens. Almost feels like a race condition of some sort.
|
# ? Mar 18, 2011 23:45 |
|
Say I have a class and two derived classes, like this. code:
|
# ? Mar 19, 2011 00:52 |
Ghost Town Perv posted:Say I have a class and two derived classes You can't create a vector that contains objects of any of those three types, but you can create a vector that contains pointers to objects of any of those types. code:
But you should not be attempting to cast up that way, in general. You should instead define an appropriate virtual method interface in CBase and implement it in the derived classes, to get the functionality you want through polymorphism. When doing this, you'll need to be careful about memory management. You'll most often be allocating the objects on the heap (with operator new) so you need to remember to delete them again, which implies you need to figure out which part of your code should be responsible for deleting the objects. You can also look into using smart pointers instead.
|
|
# ? Mar 19, 2011 01:31 |
|
Ghost Town Perv: Not directly, no; all the STL containers are homogenous. You can make it a vector of pointers (or smart pointers) to CBase, or you can make it a vector of a union of all the options, or you can figure out some other way making it homogenous, or you can roll your own crazy heterogenous vector class.
|
# ? Mar 19, 2011 01:34 |
|
nielsm posted:... Just do this; don't bother with manual memory management. Make a vector< shared_ptr<CBase> >.
|
# ? Mar 20, 2011 19:02 |
|
When I try to compile this code in visual c++ express 2010 on windows 7, it gives me a bunch of syntax errors on the brackets in the sort function:code:
code:
|
# ? Mar 22, 2011 03:10 |
|
icantfindaname posted:When I try to compile this code in visual c++ express 2010 on windows 7, it gives me a bunch of syntax errors on the brackets in the sort function: Those line numbers (9,10,11,...) aren't actually in your source file are they? I get similar errors if I don't edit out the line numbers.
|
# ? Mar 22, 2011 03:23 |
|
MutantBlue posted:Those line numbers (9,10,11,...) aren't actually in your source file are they? I get similar errors if I don't edit out the line numbers. I added them to show the lines in the error messages. On second thought, here's the whole program code:
|
# ? Mar 22, 2011 03:30 |
|
pre:$ clang -Wall qs.c qs.c:10:29: error: expected ')' void sort (int *array1, int length) ^ qs.c:6:16: note: instantiated from: #define length 16 ^ qs.c:10:11: note: to match this '(' void sort (int *array1, int length) ^ qs.c:10:29: error: parameter name omitted void sort (int *array1, int length) ^ qs.c:6:16: note: instantiated from: #define length 16 ^ pre:$ gcc -Wall qs.c qs.c:10:29: error: expected ‘;’, ‘,’ or ‘)’ before numeric constant
|
# ? Mar 22, 2011 03:33 |
|
icantfindaname posted:I added them to show the lines in the error messages. On second thought, here's the whole program That #define tells the preprocessor to replace "length" with "16" everywhere it sees it. This makes the next line look like "void sort (int *array1, int 16)" and the "int 16" is where the error is.
|
# ? Mar 22, 2011 03:34 |
|
icantfindaname posted:I added them to show the lines in the error messages. On second thought, here's the whole program #define does a textual replacement. You #define'd "length" to mean 16. This means that line 9 is equivalent to void sort (int *array1, int 16) which doesn't make any sense.
|
# ? Mar 22, 2011 03:37 |
MutantBlue posted:That #define tells the preprocessor to replace "length" with "16" everywhere it sees it. This makes the next line look like "void sort (int *array1, int 16)" and the "int 16" is where the error is. Lesson to take: Always write macros with uppercase, like LENGTH. Or, since you're actually writing C++ (your file is named .cpp), make a proper constant: code:
|
|
# ? Mar 22, 2011 03:37 |
|
nielsm posted:Lesson to take: Always write macros with uppercase, like LENGTH. Or, since you're actually writing C++ (your file is named .cpp), make a proper constant: If you're actually writing C++ use std::sort()
|
# ? Mar 22, 2011 03:39 |
MutantBlue posted:If you're actually writing C++ use std::sort() It looks like it might be some kind of homework or other. The C standard library also has a qsort() function.
|
|
# ? Mar 22, 2011 03:41 |
|
nielsm posted:It looks like it might be some kind of homework or other. The C standard library also has a qsort() function. Yep, and thanks, it works now
|
# ? Mar 22, 2011 03:46 |
|
nielsm posted:Lesson to take: Always write macros with uppercase, like LENGTH. Or, since you're actually writing C++ (your file is named .cpp), make a proper constant: Basically, do something so you don't reuse global variable names in local scope because it won't ever make things easier, and will sometimes make things annoying as gently caress.
|
# ? Mar 22, 2011 04:09 |
I want to overload the << and >> operators on my class to make it easier to print and read to it. But I'm getting this error: utils.h:33: error: no match for 'operator>>' in 's >> city->cityinfo_c::name' here is the code: code:
|
|
# ? Mar 22, 2011 05:34 |
|
A MIRACLE posted:
You're about to stuff a bunch of stuff into that cityinfo_c, it doesn't make sense for it to be const.
|
# ? Mar 22, 2011 05:39 |
|
How do you guys handle memory profiling? I've been trying to use ps -u and valgrind and I've been sort of confused by the output - I know it's sort of naïve to say I want to know 'only' the heap and stack usage - but what values are most accurate for measuring this? What do you look at? I'm writing a program that needs to be really memory efficient for a large number of entries that each get malloced. I had been using the resident set size field of ps -u, but I think the heap isn't represented by it.
|
# ? Mar 25, 2011 16:36 |
|
Clobbersaurus posted:How do you guys handle memory profiling? I use the massif for valgrind. As long as you are using a semi recent version, it should show heap and memory usage and break down where they occured and how much is being used by them. Massif's whole job is memory profiling.
|
# ? Mar 25, 2011 17:25 |
|
HFX posted:I use the massif for valgrind. As long as you are using a semi recent version, it should show heap and memory usage and break down where they occured and how much is being used by them. Massif's whole job is memory profiling. Cool! So if I'm interpreting this correctly - the total heap usage is then the mem_heap_B + mem_head_extra_B?, where the 'extra' is just the overhead on malloc references and heap structure and all that?
|
# ? Mar 25, 2011 18:10 |
|
Clobbersaurus posted:Cool! So if I'm interpreting this correctly - the total heap usage is then the mem_heap_B + mem_head_extra_B?, where the 'extra' is just the overhead on malloc references and heap structure and all that? You got it. Extra might also include some bytes not yet allocated to you, but are in the same page.
|
# ? Mar 25, 2011 23:58 |
|
|
# ? Jun 3, 2024 10:47 |
|
HFX posted:I use the massif for valgrind. As long as you are using a semi recent version, it should show heap and memory usage and break down where they occured and how much is being used by them. Massif's whole job is memory profiling. Seconding this, with the addition that Massif Visualizer is freaking fantastic for viewing the output. That said, learning a bit about malloc works on your platform (16 byte chunks, linux's fastbin thingy) is probably just as helpful.
|
# ? Mar 26, 2011 03:04 |