Go Down

Topic: About low-level programming... (Read 7185 times) previous topic - next topic

waterlubber

Quote
I can understand function pointer and static friend. But what does it mean by virtual static friend then? If a function is static, can it be overridden by a class that inherits from the base class?


Quote

The first statement will cause a version of swap that works on ints to be compiled, and the second will cause a version of swap that works on students to be compiled.


POP! (That's a brain explosion)


---And if you think that's hard, try coding Android ADT (I couldn't get a FUDGING BUTTON to work.)

---And if you think the ADT is hard, try taking a state test. You need a PhD in Cryptology AND in Psychiatry to figure that out.

pYro_65


I can understand function pointer and static friend. But what does it mean by virtual static friend then? If a function is static, can it be overridden by a class that inherits from the base class?

Where does volatile apply? The pointer is changing value so don't optimize code that accesses its value in a register or memory?

Templated is beyond my understanding. I don't use templates yet.


Hmmm, there are a few things not right, I wouldn't take that little quote as anything more than humor.

Static friend is redundant, static or friend should be used,
You cannot take pointers to template functions only a particular instantiation:  foo<>, foo<int>, which is not a template any more but a fully defined entity.
Virtual static is wrong, a static non-member is not bound to any object and therefore has no 'virtual' implications. This also applies to friend, these keywords imply a non-member entity.
Forum Mod anyone?
https://arduino.land/Moduino/

westfw

Quote
POP! (That's a brain explosion)

What?  In C, you'd have a swap function to swap two integers, so that (1, 2) would become (2,1):
Code: [Select]
void swap(int *a, int *b) {
  int temp;
  temp = *a;
  *a = *b;
   *b = temp;
}

But if you wanted to have a library of swap functions for different datatypes, you'd need to implement swap_int(), swap_long(), swap_float(), swap_string(), and so on.  Plus, any data types that you defined yourself.
Code: [Select]
void swap_string(char **a, int **b) {
  char * temp;
  temp = *a;
  *a = *b;
   *b = temp;
}


C++ would make this somewhat easier, because you can have 'function overloading", where the same function name with different arguments results in separate code:
Code: [Select]
void swap(int *a, int *b) {
  int temp;
  temp = *a;
  *a = *b;
   *b = temp;
}
void swap(char **a, int **b) {
  char * temp;
  temp = *a;
  *a = *b;
   *b = temp;
}

(now, the top-level code can say "swap(a,b)" for several types of a and b.)
But - note that the actual CODE in those functions stays the same regardless of the types of arguments, except for the type specifications in the header and for "temp"; what you really want, so you can avoid rewriting the same code over and over, is to somehow pass that part of the function - the type - as an argument to some sort of macro.  (I could almost imagine this as a C preprocessor macro, at least for an inline swap.  But... Ugly!)
Code: [Select]
template <typename my_type>
void swap(my_type *a, my_type *b)
{
   my_type temp;
   temp = *a;
   *b = *a;
   *b = temp;
}

This is what C++ templates give you.  (one of the things they give you, anyway.)  It's made more useful by also providing a "Standard Template Library" (STL) that provides a lot of common data structures and algorithms.  So you can SORT your VECTOR of (user-defined) THING_TYPES without having to write any code for SORT, or VECTOR (a growable array-like thing) that is specific to THING_TYPE (other than a "compare-to" function.)  (again, you can almost do this in C, given (dangerous) void* pointers, macros, and so on.  But the C++ version is much prettier and less subject to being wrong.)

SirNickity

Oh.. that's kinda cool.  :)

I have to admit, I've been tempted to use a C++ compiler on my C programs just to take advantage of function overloading.  That's one heckuva useful tool.

JChristensen


I have to admit, I've been tempted to use a C++ compiler on my C programs just to take advantage of function overloading.  That's one heckuva useful tool.


A slippery slope that may be, yesssss. Leads to the Dark Side, it does  ;)

udoklein

If you really want to make your mind explode try to analyze template metaprogrammed code. After reading about template metaprogramming I wondered if I could achieve similar effects with the macro processor. Of course this is not the same but close http://blog.blinkenlight.net/experiments/removing-flicker/knight-rider-no-flicker/ ;)
Check out my experiments http://blog.blinkenlight.net

nickgammon

Templates are extremely useful, particularly if you get into the Standard Template Library (STL).

I admit it can be a little hard to get started, but once you do, your life is so much easier. Linked lists, maps, vectors, strings, all much much easier than writing yourself.

Here's a simple example. Say you have a structure of widgets, and you want to have any number of them in a linked list:

Code: [Select]

#include <iterator>
#include <list>
#include <pnew.cpp>

typedef struct
 {
 int foo;
 char bar;
 byte fubar [10];
 }  widget;  

std::list<widget *> myList;
 
void setup ()
{
 widget * w;
 
 w = new widget;
 myList.push_back (w);
 w = new widget;
 myList.push_back (w);  
}  // end of setup

void loop () {}


Done. You can add to the front or the back of the list. You can traverse the list forwards or backwards. If you find a particular item you can delete it from the middle, front or back. You don't need to muck around with "next" or "previous" pointers, like you would if you do it manually.

You have other container types like maps (for key/value pairs), vectors (where you want to go straight to item 42), and so on. Queues and stacks are variants on vectors, however there is a deque type (double-ended queue) which is more efficient for those applications.

There are various utilities in the library, for example you can sort containers, or do things like delete every entry matching a certain condition.

Containers can be pointers (as in the example above) or actual data (not pointers) provided they can be copied and assigned.

Below is a similar example, however this time we use widget directly (not a pointer to widget):

Code: [Select]

#include <iterator>
#include <list>
#include <pnew.cpp>

typedef struct
  {
  int foo;
  char bar;
  byte fubar [10];
  }  widget; 

std::list<widget> myList;
 
void setup ()
{
  widget w;
 
  myList.push_back (w);
  myList.push_back (w);
   
}  // end of setup

void loop () {}
Please post technical questions on the forum, not by personal message. Thanks!

More info: http://www.gammon.com.au/electronics

SirNickity

I wrote some of my own libraries (a reinvented wheel no doubt) to handle lists and ring buffers and that sort of thing.  Easy enough, but yeah, not having to do it at all is easier.  Not to mention the maintenance is done for you, and everyone knows how it works just by seeing the initialization.

Key/value pairs are one thing I miss when writing C after working in scripting and web development languages.  I love hashes.  Very handy for indexing and validity checks ($sanitized = $valid_terms[$input]) etc.  Inefficient as all heck, I'm sure...

Go Up