don't click here

Some C/C++ questions

Discussion in 'Technical Discussion' started by SegaLoco, Nov 7, 2009.

  1. SegaLoco

    SegaLoco

    W)(at did you say? Banned
    I recently got a pretty good grasp on the object-oriented side of C++, but I still don't know everything when it comes to templates and overloading. IIRC you can overload methods, but can you overload templates. Also, can somebody explain protected variables and dynamic vs. static memory. Also, is it good practice in C to use a struct based system for pseudo object-orientation? As you that know me can see, I am getting better =D
     
  2. Andlabs

    Andlabs

    「いっきまーす」 Wiki Sysop
    2,175
    1
    0
    Writing my own MD/Genesis sound driver :D
    Not exactly. You can't do this:
    Code (Text):
    1. template<class T> class X {
    2. &nbsp;&nbsp;&nbsp;&nbsp;// ...
    3. };
    4. template<class T, class U> class X {
    5. &nbsp;&nbsp;&nbsp;&nbsp;// ...
    6. };
    However, you can specify alternate versions of a class for each possible template parameter. For example:
    Code (Text):
    1. template<class T> MyClass {
    2. &nbsp;&nbsp;&nbsp;&nbsp;T *t;
    3. public:
    4. &nbsp;&nbsp;&nbsp;&nbsp;void doSomething() { t++; }
    5. };
    6. template<int> MyClass {
    7. &nbsp;&nbsp;&nbsp;&nbsp;int t;
    8. public:
    9. &nbsp;&nbsp;&nbsp;&nbsp;void doSomething() { t = 0; }
    10. };
    (Sorry, I can't think of a good example tonight.) You can also make template arguments optional. For instance:
    Code (Text):
    1. namespace std {
    2. &nbsp;&nbsp;&nbsp;&nbsp;template<class T, class Alloc = allocator<T> > class vector { /* ... */ };
    3. }
    might be the declaration for your compiler's std::vector class. You only need to worry about custom allocators if you need to do your own memory management, so most people ignore the Alloc argument and the standard library will load its own, which just does new and delete.

    Code (Text):
    1. class Base {
    2. &nbsp;&nbsp;&nbsp;&nbsp;int privateInt;
    3. protected:
    4. &nbsp;&nbsp;&nbsp;&nbsp;int protectedInt;
    5. public:
    6. &nbsp;&nbsp;&nbsp;&nbsp;int publicInt;
    7. };
    8. class Derived : Base {
    9. public:
    10. &nbsp;&nbsp;&nbsp;&nbsp;void f();
    11. };
    12. void Derived::f()
    13. {
    14. &nbsp;&nbsp;&nbsp;&nbsp;this->privateInt = 0; // WRONG; private doesn't carry through
    15. &nbsp;&nbsp;&nbsp;&nbsp;this->protectedInt = 1; // OK; protected variables carry through
    16. &nbsp;&nbsp;&nbsp;&nbsp;this->publicInt = 2; // OK
    17. }
    18. void g(Derived &d) // global function
    19. {
    20. &nbsp;&nbsp;&nbsp;&nbsp;d.privateInt = 0; // WRONG; private used outside scope
    21. &nbsp;&nbsp;&nbsp;&nbsp;d.protectedInt = 1; // WRONG; outside the class, protected == private
    22. &nbsp;&nbsp;&nbsp;&nbsp;d.publicInt = 2; // OK
    23. }
    Does this make it clear?

    Code (Text):
    1. void f()
    2. {
    3. &nbsp;&nbsp;&nbsp;&nbsp;static int x = 0; // this variable is in static memory; it exists until the program quits and &x will always yield the same value in every function call
    4. &nbsp;&nbsp;&nbsp;&nbsp;int *y = new int; // this variable is in dynamic memory; it exists until it is deleted or the program quits; also y will point to a different memory address each time
    5. &nbsp;&nbsp;&nbsp;&nbsp;int z = 0; // this is also in dynamic memory and is created each time the function is called on the call stack (so &z is different each time) and is destroyed when the functio nreturns
    6. }
    You could; see gobject. However, people would rather you write in pure C++.

    On a side note, Ken Thompson's (the Unix co-creator) extensions to C in Plan 9 from Bell Labs let you do simple inheritance:
    Code (Text):
    1. struct Lock { /* multithreaded locks */ };
    2. struct AsynchronousObject {
    3. &nbsp;&nbsp;&nbsp;&nbsp;int data;
    4. &nbsp;&nbsp;&nbsp;&nbsp;struct Lock;
    5. };
    6.  
    7. extern void lock(struct Lock *l);
    8. void f(struct AsynchronousObject *o) { lock(o); }
     
  3. SegaLoco

    SegaLoco

    W)(at did you say? Banned
    So...protected variables private globally, but are passed down through inheritance. As for memory, I kinda get it, does it have to do with how long the variable exists in the programs existance. As for the templating, I am not that far yet, I meant
    Code (Text):
    1. template <class myType> doThis(myType myVar)
    2.  
    3. vs.
    4.  
    5. template <class myType> doThis(myType myVar, myType myOtherVar)
     
  4. Andlabs

    Andlabs

    「いっきまーす」 Wiki Sysop
    2,175
    1
    0
    Writing my own MD/Genesis sound driver :D
    Yes, and it also has to do with when the memory is created. Static = compile time, dynamic = run time.

    Oh, I thought you meant class templates. Function templates have more complicated rules. I suggest you check a C++ reference book for that.
     
  5. SegaLoco

    SegaLoco

    W)(at did you say? Banned
    K, I really need to get ungrounded from my wifi card. PSP is great, but Firefox makes internet easy.
     
  6. Ultima

    Ultima

    Games Publisher Tech Member
    2,398
    1
    18
    London, England
    Publishing mobile games!
    You can have overloaded template functions, just as you can with regular functions.

    Code (Text):
    1. template <class T>
    2. T* create(float x = 0, float y = 0)
    3. {
    4. &nbsp;&nbsp;&nbsp;&nbsp;//function which auto-names created object
    5. }
    6.  
    7. template <class T>
    8. T* create(std::string name, float x = 0, float y = 0)
    9. {
    10. &nbsp;&nbsp;&nbsp;&nbsp;//function which uses specified name
    11. }
     
  7. SegaLoco

    SegaLoco

    W)(at did you say? Banned
    Cool. Anybody got a good PDF that lists out all the parts of the standard C++ library in a style similar to javadoc or the back of the KnR book. Also, inheritance in C++, is it like extends in Java.
    Code (Text):
    1. class myClass extends yourClass
    2.  
    3. vs.
    4.  
    5. class myClass : yourClass
     
  8. Andlabs

    Andlabs

    「いっきまーす」 Wiki Sysop
    2,175
    1
    0
    Writing my own MD/Genesis sound driver :D
    No, but there is http://www.cppreference.com/.

    Almost. C++ has rules for how protected and public work in inheritance that are not very useful for most purposes. You would just have to say
    Code (Text):
    1. class myClass : public yourClass
    The public keeps the same precedence rules as the parent class.
     
  9. SegaLoco

    SegaLoco

    W)(at did you say? Banned
    Okay, a few questions. What are the differences between, pros/cons, and significance of:
    Code (Text):
    1. int *ip;
    2. ip = (int *) malloc(sizeof (int));
    3. *ip = 3;
    4.  
    5. /* and */
    6.  
    7. int *ip;
    8. *ip =3;
    9.  
    10. /* and */
    11.  
    12. int ip;
    13. ip = 3;
     
  10. kcowolf

    kcowolf

    Oldbie
    23
    4
    3
    In the first one, ip points to memory allocated from the heap. You need to free() that memory before your program finishes or it will be leaked. However, you can use that memory from anywhere in your program as long as you maintain a pointer to it.

    The third one is allocated on the stack. As soon as you are out of your current scope (which usually means the end of the current function), the current "plate" is popped and that memory is returned to the system to be used later. Even if you managed to maintain a pointer to the exact memory address where ip is being allocated, it would not be safe to use it since the compiler has assumed you are no longer going to use it and will allow it to be used elsewhere.

    The second one is bad because the value of ip is unknown garbage, and then you dereference it. In other words, you've just written "3" to a random location in memory.

    The pros/cons between stack and heap allocation really depend on what you need to do. For one thing, depending on what kind of system you are working with (for example, an embedded system such as a handheld GPS), you need to be careful about allocating a large chunk of stack memory since you may overflow the stack, but if you only need your variable for the length of a short function, it'd be cumbersome to malloc/free it.

    Let me know if that gives you the information you want, or if there's anything I can clarify.
     
  11. Nibble

    Nibble

    Oldbie
    This may be obvious already, but I just want to add that just because it's a pointer, doesn't mean that it has to be on the heap. I often see people repeat the misconception that "pointer = heap", when it's not necessarily true, since pointers can point to either stack or heap memory.

    As evidenced by code like this:
    Code (Text):
    1. int num = 42;
    2. int *p = &num;
    'p' in this case is a pointer to a stack variable (and should not be used if the variable goes out of scope).
     
  12. kcowolf

    kcowolf

    Oldbie
    23
    4
    3
    That's true. Thanks for clarifying that. Pointers are *usually* used to allocate memory on the heap, but that doesn't have to be the case.

    The most helpful way I learned to think about it is: "pointer == memory address". You have to keep in mind what happens to that memory when your function and your program end.
     
  13. SegaLoco

    SegaLoco

    W)(at did you say? Banned
    I think I meant static on the second one. As for the others, I kinda get it, is mallocs purpose to make an absolute sized space for a variable instead of just randomly putting it somewhere?
     
  14. Andlabs

    Andlabs

    「いっきまーす」 Wiki Sysop
    2,175
    1
    0
    Writing my own MD/Genesis sound driver :D
    You're asking two different questions. malloc(size) will find free memory of the given size and return its address. This can be any address at any time. This address will always point to locations that don't already hold data. You can look up implementations of malloc in several places to understand what it does.
     
  15. SegaLoco

    SegaLoco

    W)(at did you say? Banned
    Ohhhh, I think I get it now. *malloc(size_t x) just attempts, when possible, to get you a pointer to a guaranteed chunk of x bytes?
     
  16. Andlabs

    Andlabs

    「いっきまーす」 Wiki Sysop
    2,175
    1
    0
    Writing my own MD/Genesis sound driver :D
    Yes. Don't use * — that will try to dereference the new memory, which fails (because it's void *).
     
  17. SegaLoco

    SegaLoco

    W)(at did you say? Banned
    New question, this time regarding GTK+. I understand UI building and the rudiments of the signal/callback system, but I am stuck now. How do I access the return value of a callback. I have one where when I click a button, it returns the active text in a combo box, but I have no clue how to access the returned string. I'm an idiot, disregard that. A question though, how can I make a callback operate on multiple g_objects. Do I put them all in g_signal_connect or just make separate callbacks for all.
     
  18. GerbilSoft

    GerbilSoft

    RickRotate'd. Administrator
    2,971
    76
    28
    USA
    rom-properties
    You'll need to call g_signal_connect() for each g_object.
     
  19. SegaLoco

    SegaLoco

    W)(at did you say? Banned
    Surprisingly, I have no questions besides, what should I try to learn now? I have nailed the Standard C Library, and GTK+ is coming easy. Should I work more on graphics with GDK or OpenGL, or should I try some other types of libraries like audio libraries. I just dunno what direction is best to go. I'm not *THAT* interested in game development, but I can't think of a practical application that doesn't already exist.
     
  20. Ultima

    Ultima

    Games Publisher Tech Member
    2,398
    1
    18
    London, England
    Publishing mobile games!
    Most audio libraries are piss easy to use. Maybe try learning to use something like wxWidgets? I dunno.