c++ and C

C++ and C. Moving on. Im having difficulty understanding class. I have read a lot, but maybe its the use of the word class im having trouble with. Is there a better descriptive expression

tried - http://en.wikipedia.org/wiki/C%2B%2B_classes -?

A simplistic definition would be to think of a class as a representation of the object, but not the object itself.

Kinda like how a schematic is a representation of a physical circuit, but it isn't the physical circuit itself.

...or how an architectural plan drawing of a house isn't the actual house after it is built.

You need to "instantiate" the class (keyword "new") in order to get an object that can be utilized.

/I've probably confused you more...

A Class is a way to mold/wrap up related code and data into a name. A Class is a design. It's a way to organize your program that has the compiler doing most of the fiddly interlink work.

You use the Class to make an object that you interact with through its member functions. The object has data in RAM and a name. It uses the Class member functions. It calls itself 'this'. You can make whole arrays of objects and code them to interact.

But please on small memory systems, avoid routinely creating and deleting objects. Space for things that come and go can be in a pre-defined buffer made to hold as many as can happen at once even if the code has to limit that number. That way you control the heap and it doesn't get shotgunned which when you operate on 2k to 8k is bad and besides, it slows down memory allocation and reaches for the stack. Arduino, deallocation, be careful, not casual. Best to just don't.

If I have files to access, I'll write a Class with buffer pointers that when an object is made it looks for the file and opens it if it's there or creates one if not and then readies the buffer and pointers for my reading/writing pleasure. Then when I write a program that uses that Class, I provide a buffer and the Class does the first 9 yards for me. The file is just there through the buffer like serial is just there through Serial.

You can wrap Classes together, make a Class that is another Class but with certain changes..... You can make objects that make other objects but again, watch memory limits, plan ahead.

Look at how you use Serial, which is a code object. Or SD or most other libraries, all written as Classes.

Think of an orchestra.

Each musician is trained to use his or her instrument, each person knows a set of rules when to play when to stop, and when combined with all the other instruments they all behave as 1, they're not all playing different music.

The conductor is you.

PianoPlayer.play (); Delay (1000); ViolenPlayer2.play ();

So you write a class foundation which has the basic properties of all, they all have names.

Since each class is encapsulated allof it's variables, functions are all together so you don't need to worry about overwriting variables because they're all tucked away inside the class.

But as you can see

So am i correct in asserting its a collection of functions with locally defined variables that any function can use within the class only.

Yeah, except in cpp/java you can have private/public sections where only that class an access the properties. And theclass.something (); wont exist unless called within the class unless you specify it to be public

I love Arduino because I can get away coding like I did back in 1994 learning C.

Did not we used to call them function libraries ?

A Class encapsulates a set of data and behaviors that describe an object. I got taught things like a car, it has behavior like moving and turning and it has data that describes it like the number of wheels or its color. You define a class like you design a car and then you create instances of that class in the same way you would make a car. Each car is an instance of its design in the same way each object is an instance of it's class. It's a class of objects.

Thanks , thats probably the most understandable description i have seen.

Im sloooowly getting the idea.

Boardburner2: So am i correct in asserting its a collection of functions with locally defined variables that any function can use within the class only.

You have control over visibility of inside the object from outside. When I made file objects, I made the record fields into public variables.

The potential of Classes goes levels beyond that but there's no reason they can't do simple tasks easily.

When you’re just using their most basic features (bundling data and functions together), I’m not sure there’s really much practical difference between a well-designed C function library and a C++ class. When it comes down to using one, it’s the difference between writing

doSomething(thingie);

or

thingie.doSomething();

Encapsulation isn’t really a big distinction, either - there are a couple tricks (of varying levels of elegance) that you can use to achieve encapsulation in C. My favorite is to just take advantage of the fact that C doesn’t actually require you to define a struct’s contents in the header file - you can declare a struct in the *.h, and put the definition in the *.c along with the rest of the implementation details. All the encapsulation with none of the OOP.

The spot where OOP really starts looking different is when you get into features like polymorphism, which lets you start defining equivalence classes among your abstract data types. For example, in C++ you can do something like this:

// interface defining a set of integers
class ISet {
  public:
    // adds an item to the set
    virtual void insert(int i) = 0;
    // gets the number of items in the set
    virtual int numberOfItems() = 0;
    // gets the ith item of the set. 
    virtual int getItem(int itemNumber) = 0;
}

// array-based implementation
class ArrayBasedSet : public ISet {
  public:
    virtual void insert(int i) { /* implementation */ }
    virtual int numberOfItems() { /* implementation */ }
    virtual int getItem(int itemNumber) { /* implementation */ }
  private:
    // more implementation details
}

// array-based implementation
class HashTableBasedSet : public ISet {
  public:
    virtual void insert(int i) { /* implementation */ }
    virtual int numberOfItems() { /* implementation */ }
    virtual int getItem(int itemNumber) { /* implementation */ }
  private:
    // more implementation details
}

(yes I know that strictly speaking getItem() totally violates what it means to be a set, and the C++ bits are probably poorly styled, but bear with me. . .)

The first definition creates a pure abstraction. It defines some basic rules for how a set of numbers should behave, but is completely open-ended about how it’s implemented. It’s not just a struct with functions attached, it’s a struct where the functions are themselves almost a sort of variable - any given instance of ISet could have a different value for insert(). You can’t actually create an ISet directly, because none of its functions are defined. Instead, you have to create concrete implementations that supply specific values for the functions. In the example I mocked out two examples, ArrayBasedSet and HashTableBasedSet. They have some different characteristics that might make them more suited for one situation or the other. The array-based one will use less memory but be relatively slow for adding and removing items, searching, or both. A hash-based one will run fast but consume more memory (and is therefore probably a terrible choice for Arduino most of the time, but this is just an example). However, the key thing is, they’re both still an ISet. And that means that you can write code that is meant to work with an ISet, and it can work with either of the concrete classes without caring about the difference. For example:

// takes the union of two sets, and returns it as a new set.
public ISet* Union(ISet* set1, ISet* set2)
{
    HashTableBasedSet newSet();

    // add items from set1 to the new set
    for(int i = 0; i < set1->numberOfItems(); i++) {
      newSet.insert(set1->getItem(i));
    }
 
    // add items from set2 to the new set
    for(int i = 0; i < set2->numberOfItems(); i++) {
      newSet.insert(set2->getItem(i));
    }

    return &newSet;
}

The above code can take two array-based sets, two hashtable-based sets, or objects of some kind of ISet that never even existed when the function was written, and easily take the union of them. A little bit like how in C an add() function can take all sorts of integers and add them together, regardless of what their values are. That kind of flexibility is where OOP really starts to matter, and it’s tricky to achieve with straight C.

(That said, it also comes at some cost in terms of memory use and performance, so it’s probably not something you’d want to be doing on a really constrained environment like Arduino. Which gets us back to the choice between C and C++ being more question of which style of programming you’re more used to than anything else.)

That's some of it. I like to start beginners off easier.

A lot of libraries are implemented as class objects.

From the point of view of an OOP newbie, I look at it like this:

In C, you have variables and functions. To maintain a persistent state, you have to use a struct or variable as the "handle" for that state. Then, when you call functions, you pass that variable, or its pointer, so the function has access to it and can act appropriately.

typedef struct { .... } filehandle;
filehandle  MyFile;

file_open(MyFile, fname, opts);
file_read(MyFile, buf, len);
file_write(MyFile, buf, len);
file_close(MyFile);

In C++, you combine those functions and the variables necessary to maintain state into an "object". They are inseparable from that point on. Because people like new things to have new names, the functions become "methods", and the variables become "members". (Although you'll also hear of member functions or member variables.)

class File { ... }

MyFile = new(File);

MyFile.open(fname);
MyFile.read(buf, len);
MyFile.write(buf, len);
MyFile.close();

You no longer have to maintain the struct handle, since the object contains that data now. In such a simplistic example, this is almost entirely a preference thing and maybe doesn't do all that much for clarity of convenience. However, in larger projects, especially where objects may interact with other objects, it's much easier to keep track of things.

On a superficial level, it keeps the syntax cleaner. Instead of prefacing all your standard functions with a distinguishing name, like file_open or fileOpen if you're a camel-case fan, you can use short, intuitive verbs. There's no need to worry about clashing with other ambiguous function names since they're specific to the class itself, and only exist within that namespace (if you'll forgive the misuse of that term.)