C++ Programming/Classes

Classes
Classes are used to create user defined types. An instance of a class is called an object and programs can contain any number of classes. As with other types, object types are case-sensitive.

Classes provide encapsulation as defined in the Object Oriented Programming (OOP) paradigm. A class can have both data members and functions members associated with it. Unlike the built-in types, the class can contain several variables and functions, those are called members.

Classes also provide flexibility in the "divide and conquer" scheme in program writing. In other words, one programmer can write a class and guarantee an interface. Another programmer can write the main program with that expected interface. The two pieces are put together and compiled for usage.

Declaration
A class is defined by:

An object of type MyClass (case-sensitive) is declared using:


 * by default, all class members are initially private.
 * keywords public and protected allow access to class members.
 * classes contain not only data members, but also functions to manipulate that data.
 * a class is used as the basic building block of OOP (this is a distinction of convention, not of language-enforced semantics).


 * A class can be created
 * before main is called.
 * when a function is called in which the object is declared.
 * when the "new" operator is used.


 * Class Names
 * Name the class after what it is. If you can't determine a name, then you have not designed the system well enough.
 * Compound names of over three words are a clue your design may be confusing various entities in your system. Revisit your design. Try a CRC card session to see if your objects have more responsibilities than they should.
 * Avoid the temptation of naming a class something similar to the class it is derived from. A class should stand on its own. Declaring an object with a class type doesn't depend on where that class is derived from.
 * Suffixes or prefixes are sometimes helpful. For example, if your system uses agents then naming something DownloadAgent conveys real information.

A fundamental concept of Object Oriented (OO) recommends an object should not expose any of its implementation details. This way, you can change the implementation without changing the code that uses the object. The class, by design, allows its programmer to hide (and also prevents changes as to) how the class is implemented. This powerful tool allows the programmer to build in a 'preventive' measure. Variables within the class often have a very significant role in what the class does, therefore variables can be secured within the private section of the class.
 * Data Abstraction

Access labels
The access labels Public, Protected and Private are used within classes to set access permissions for the members in that section of the class. All class members are initially private by default. The labels can be in any order. These labels can be used multiple times in a class declaration for cases where it is logical to have multiple groups of these types. An access label will remain active until another access label is used to change the permissions.

We have already mentioned that a class can have member functions "inside" it; we will see more about them later. Those member functions can access and modify all the data and member function that are inside the class. Therefore, permission labels are to restrict access to member function that reside outside the class and for other classes.

For example, a class "Bottle" could have a private variable fill, indicating a liquid level 0-3 dl. fill cannot be modified directly (compiler error), but instead Bottle provides the member function sip to reduce the liquid level by 1. Mywaterbottle could be an instance of that class, an object.

These keywords, private, public, and protected, affect the permissions of the members—whether functions or variables.

public
This label indicates any members within the 'public' section can be accessed freely anywhere a declared object is in scope.

private
Members defined as private are only accessible within the class defining them, or friend classes. Usually the domain of member variables and helper functions. It's often useful to begin putting functions here and then moving them to the higher access levels as needed so to reduce complexity.

(This is an example where the default copy constructor will do the same thing.)

protected
The protected label has a special meaning to inheritance, protected members are accessible in the class that defines them and in classes that inherit from that base class, or friends of it. In the section on inheritance we will see more about it.

Data members
Data members are declared in the same way as a global or function variable, but as part of the class definition. Their purpose is to store information for that class and may include members of any type, even other user-defined types. They are usually hidden from outside use, depending on the coding style adopted, external use is normally done through special member functions.

Subsumption property
Subsumption is a property that all objects that reside in a class hierarchy must fulfill: an object of the base class can be substituted by an object that derives from it (directly or indirectly). All mammals are animals (they derive from them), and all cats are mammals. Therefore, because of the subsumption property we can "treat" any mammal as an animal and any cat as a mammal. This implies abstraction, because when we are "treating" a mammal as an animal, the only information we should know about it is that it lives, it grows, etc, but nothing related to mammals.

This property is applied in C++, whenever we are using pointers or references to objects that reside in a class hierarchy. In other words, a pointer of class animal can point to an object of class animal, mammal or cat.

Let's continue with our example:

In the last lines of the example there is cast of a pointer to Animal, to a pointer to Cat. This is called "Downcast". Downcasts are useful and should be used, but first we must ensure that the object we are casting is really of the type we are casting to it. Downcasting a base class to an unrelated class is an error. To resolve this issue, the casting operators <>, or <> should be used. These correctly cast an object from one class to another, and will throw an exception if the class types are not related. eg. If you try:

Then, the app will throw an exception, as a cat is not a motorbike. Static_cast is very similar, only it will perform the type checking at compile time. If you have an object where you are not sure of its type then you should use, and be prepared to handle errors when casting. If you are downcasting objects where you know the types, then you should use. Do not use old-style C casts as these will simply give you an access violation if the types cast are unrelated.

Local classes
A local class is any class that is defined inside a specific statement block, in a local scope, for instance inside a function. This is done like defining any other class, but local classes can not however access non-static local variables or be used to define static data members. These type of classes are useful especially in template functions, as we will see later.

User defined automatic type conversion
We already covered automatic type conversions (implicit conversion) and mentioned that some can be user-defined.

A user-defined conversion from a class to another class can be done by providing a constructor in the target class that takes the source class as an argument,  or by providing the target class with a conversion operator, as.

Ensuring objects of a class are never copied
This is required e.g. to prevent memory-related problems that would result in case the default copy-constructor or the default assignment operator is unintentionally applied to a class C which uses dynamically allocated memory, where a copy-constructor and an assignment operator are probably an overkill as they won't be used frequently.

Some style guidelines suggest making all classes non-copyable by default, and only enabling copying if it makes sense. Other (bad) guidelines say that you should always explicitly write the copy constructor and copy assignment operators; that's actually a bad idea, as it adds to the maintenance effort, adds to the work to read a class, is more likely to introduce errors than using the implicitly declared ones, and doesn't make sense for most object types. A sensible guideline is to think about whether copying makes sense for a type; if it does, then first prefer to arrange that the compiler-generated copy operations will do the right thing (e.g., by holding all resources via resource management classes rather than via raw pointers or handles), and if that's not reasonable then obey the law of three. If copying doesn't make sense, you can disallow it in either of two idiomatic ways as shown below.

Just declare the copy-constructor and assignment operator, and make them private. Do not define them. As they are not protected or public, they are inaccessible outside the class. Using them within the class would give a linker error since they are not defined.

Remember that if the class uses dynamically allocated memory for data members, you must define the memory release procedures in destructor ~C  to release the allocated memory.

A class which only declares these two functions can be used as a private base class, so that all classes which privately inherits such a class will disallow copying.

Container class
A class that is used to hold objects in memory or external storage is often called a container class. A container class acts as a generic holder and has a predefined behavior and a well-known interface. It is also a supporting class whose purpose is to hide the topology used for maintaining the list of objects in memory. When it contains a group of mixed objects, the container is called a heterogeneous container; when the container is holding a group of objects that are all the same, the container is called a homogeneous container.

Singleton class
A Singleton class is a class that can only be instantiated once (similar to the use of static variables or functions). It is one of the possible implementations of a creational pattern, which is fully covered in the Design Patterns Section of the book.

de:C++-Programmierung: Klassen Programación en C++/Objetos y Clases Programmation C++/Les classes C++/Czym jest obiekt Programar em C++/Classes