class
, struct
or union
(the first two are collectively referred to as non-union classes) that has data and functions (also called class
is ''private''. The private members are not accessible outside the class; they can be accessed only through member functions of the class. The public members form an interface to the class and are accessible outside the class.
Instances of a class data type are known as objects and can contain member variables, constants, member functions, and overloaded operators defined by the programmer.
Differences between a struct
and a class
in C++
class
keyword has private members and base classes by default. A structure is a class defined with the struct
keyword.Aggregate classes
An aggregate class is a class with no user-declared constructors, no private or protected non-static data members, no base classes, and no virtual functions.POD-structs
A POD-struct (Plain Old Data Structure) is a non-union aggregate class that has no non-static data members of type non-POD-struct, non-POD-union (or array of such types) or reference, and has no user-defined assignment operator and no user-defined destructor. A POD-struct could be said to be the C++ equivalent of a Cstruct
. In most cases, a POD-struct will have the same memory layout as a corresponding struct declared in C. For this reason, POD-structs are sometimes colloquially referred to as "C-style structs".
Properties shared between structs in C and POD-structs in C++
*Data members are allocated so that later members have higher addresses within an object, except where separated by an access-specifier.Declaration and usage
C++ classes have their own members. These members include variables (including other structures and classes), functions (specific identifiers or overloaded operators) known as member functions, constructors and destructors. Members are declared to be either publicly or privately accessible using thepublic:
and private:
access specifiers respectively. Any member encountered after a specifier will have the associated access until another specifier is encountered. There is also inheritance between classes which can make use of the protected:
specifier.
Global and local class
A class defined outside all functions is a global class because its objects can be created from anywhere in the program. If it is defined within a function body then it's a local class because objects of such a class are local to the function scope.Basic declaration and member variables
Non-union classes are declared with theclass
or struct
keyword. Declaration of members are placed within this declaration.
The above definitions are functionally equivalent. Either code will define objects of type Person
as having two public data members, name
and age
. The Person
can be used as follows to create newly defined variables of the Person
datatype:
Member functions
An important feature of the C++ class are member functions. Each datatype can have its own built-in functions (referred to as member functions) that have access to all (public and private) members of the datatype. In the body of these non-static member functions, the keywordthis
can be used to refer to the object for which the function is called. This is commonly implemented by passing the address of the object as an implicit first argument to the function. Take the above Person
type as an example again:
Print
function is declared in the body of the class and defined by qualifying it with the name of the class followed by ::
. Both name_
and age_
are private (default for class) and Print
is declared as public which is necessary if it is to be used from outside the class.
With the member function Print
, printing can be simplified into:
a
and b
above are called senders, and each of them will refer to their own member variables when the Print()
function is executed.
It is common practice to separate the class or structure declaration (called its interface) and the definition (called its implementation) into separate units. The interface, needed by the user, is kept in a header and the implementation is kept separately in either source or compiled form.
Inheritance
The layout of non-POD classes in memory is not specified by the C++ standard. For example, many popular C++ compilers implement singleP
with a P* p
pointing to it might look like this in memory:
┏━━━━┓
┃P::x┃
┗━━━━┛
↑
p
An instance of C
with a P* p
pointing to it might look like this:
┏━━━━┳━━━━┓
┃P::x┃C::y┃
┗━━━━┻━━━━┛
↑
p
Therefore, any code that manipulates the fields of a P
object can manipulate the P
fields inside the C
object without having to consider anything about the definition of C
's fields. A properly written C++ program shouldn't make any assumptions about the layout of inherited fields, in any case. Using the static_cast or dynamic_cast D
inherits P
and C
, then the fields of both parents need to be stored in some order, but (at most) only one of the parent classes can be located at the front of the derived class. Whenever the compiler needs to convert a pointer from the D
type to either P
or C
, the compiler will provide an automatic conversion from the address of the derived class to the address of the base class fields (typically, this is a simple offset calculation).
For more on multiple inheritance, see virtual inheritance.
The final
keyword limits the ways in which a class can be subclassed. Subclasses of a class are prevented from overriding methods marked as final
by the parent class. Final classes cannot be inherited. This allows ''devirtualization'', the removal of the use of vtables for method lookup, thus allowing the inlining of method calls on final classes.
final
is not a Overloaded operators
In C++, operators, such as+ - * /
, can be overloaded to suit the needs of programmers. These operators are called overloadable operators.
By convention, overloaded operators should behave nearly the same as they do in built-in datatypes (int
, float
, etc.), but this is not required. One can declare a structure called Integer
in which the variable ''really'' stores an integer, but by calling Integer * Integer
the sum, instead of the product, of the integers might be returned:
struct
declaration and define the function of the operator in the global scope:
i
above represents the sender's own member variable, while k.i
represents the member variable from the argument variable k
.
The const
keyword appears twice in the above code. The first occurrence, the argument const integer& k
, indicated that the argument variable will not be changed by the function. The second incidence at the end of the declaration promises the const integer& k
, the Binary overloadable operators
Binary operators (operators with two arguments) are overloaded by declaring a function with an "identifier" ''operator (something)'' which calls one single argument. The variable on the left of the operator is the sender while that on the right is the argument.<
is not necessarily the opposite of >
.
Unary overloadable operators
While some operators, as specified above, takes two terms, sender on the left and the argument on the right, some operators have only one argument - the sender, and they are said to be "unary". Examples are the negative sign (when nothing is put on the left of it) and the "logical NOT" (!
).
Sender of unary operators may be on the left or on the right of the operator. The following is a list of unary overloadable operators:
The syntax of an overloading of a unary operator, where the sender is on the right, is as follows:
:''return_type'' operator@ ()
When the sender is on the left, the declaration is:
:''return_type'' operator@ (int)
@
above stands for the operator to be overloaded. Replace return_type
with the datatype of the return value (int
, bool
, structures etc.)
The int
parameter essentially means nothing but a convention to show that the sender is on the left of the operator.
const
arguments can be added to the end of the declaration if applicable.
Overloading brackets
The square bracket[]
and the round bracket ()
can be overloaded in C++ classes. The square bracket must contain exactly one argument, while the round bracket can contain any specific number of arguments, or no arguments.
The following declaration overloads the square bracket.
:''return_type'' operator[] (''argument'')
The content inside the bracket is specified in the argument
part.
Round bracket is overloaded a similar way.
:''return_type'' operator() (''arg1, arg2, ...'')
Contents of the bracket in the operator call are specified in the second bracket.
In addition to the operators specified above, the arrow operator (->
), the starred arrow (->*
), the new
keyword and the delete
keyword can also be overloaded. These memory-or-pointer-related operators must process memory-allocating functions after overloading. Like the assignment (=
) operator, they are also overloaded by default if no specific declaration is made.
Constructors
Sometimes programmers may want their variables to take a default or specific value upon declaration. This can be done by declaring constructors.Person
type variable can be thought of as the return value:
Person
constructor is invoked.
Default constructor
Default constructors are called when constructors are not defined for the classes.Destructors
A destructor is the inverse of a constructor. It is called when an instance of a class is destroyed, e.g. when an object of a class created in a block (set of curly braces "") is deleted after the closing brace, then the destructor is called automatically. It will be called upon emptying of the memory location storing the variables. Destructors can be used to release resources, such as heap-allocated memory and opened files when an instance of that class is destroyed. The syntax for declaring a destructor is similar to that of a constructor. There is no return value and the name of the function is the same as the name of the class with a tilde (~) in front.Similarities between constructors and destructors
*Both have same name as the class in which they are declared. *If not declared by user both are available in a class by default but they now can only allocate and deallocate memory from the objects of a class when an object is declared or deleted. *For a derived class: During the runtime of the base class constructor, the derived class constructor has not yet been called; during the runtime of the base class destructor, the derived class destructor has already been called. In both cases, the derived class member variables are in an invalid state.Class templates
In C++, class declarations can be generated from class templates. Such class templates represent a family of classes. An actual class declaration is obtained by ''instantiating'' the template with one or more template arguments. A template instantiated with a particular set of arguments is called a template specialization.Properties
The syntax of C++ tries to make every aspect of a class look like that of the basic datatypes. Therefore, overloaded operators allow classes to be manipulated just like integers and floating-point numbers,some_structure variable_name ize/code>), and pointers to classes can be dereferenced in the same way as pointers to built-in datatypes.
Memory consumption
The memory consumption of a structure is at least the sum of the memory sizes of constituent variables. Take the TwoNums
structure below as an example.
struct TwoNums ;
The structure consists of two integers. In many current C++ compilers, integers are 32-bit integers by default, so each of the member variables consume four bytes of memory. The entire structure, therefore, consumes at least (or exactly) eight bytes of memory, as follows.
+----+----+
, a , b ,
+----+----+
However, the compiler may add padding between the variables or at the end of the structure to ensure proper data alignment for a given computer architecture, often padding variables to be 32-bit aligned. For example, the structure
struct BytesAndSuch ;
could look like
+-+-+-+-+--+--+----+--------+
, c, C, D, X, s , XX, i , d ,
+-+-+-+-+--+--+----+--------+
in memory, where represents padded bytes based on 4 bytes alignment.
As structures may make use of pointers and arrays to declare and initialize its member variables, memory consumption of structures is not necessarily constant. Another example of non-constant memory size is template structures.
Bit fields
Bit field
A bit field is a data structure that maps to one or more adjacent bits which have been allocated for specific purposes, so that any single bit or group of bits within the structure can be set or inspected. A bit field is most commonly used to repre ...
s are used to define the class members that can occupy less storage than an integral type. This field is applicable only for integral types (int, char, short, long, etc.) and enumeration types (e.g. std::byte) and excludes float or double.
struct A ;
* Memory structure
4 byte int 4 byte int
2] 4] 6] 8]
a] b] ] ] ] ] ] ] ] ] ] ] ] ] ] ]
c] ] ] e] e] ] ] ] ] ] ] ] ] ] ] ]
Unions are also allowed to have bit-field members:
union A ;
Pass by reference (C++), reference
Many programmers prefer to use the ampersand (&) to declare the arguments of a function involving structures. This is because by using the dereferencing ampersand only one word (typically 4 bytes on a 32 bit machine, 8 bytes on a 64 bit machine) is required to be passed into the function, namely the memory location to the variable. Otherwise, if pass-by-value is used, the argument needs to be copied every time the function is called, which is costly with large structures.
Since pass-by-reference exposes the original structure to be modified by the function, the const
keyword should be used to guarantee that the function does not modify the parameter (see const-correctness), when this is not intended.
The ''this'' keyword
To facilitate classes' ability to reference themselves, C++ implements the this
keyword for all member functions. The this
keyword acts as a pointer to the current object. Its type is that of a pointer to the current object.
The this
keyword is especially important for member functions with the class itself as the return value:
Complex& operator+=(const Complex& c)
As stated above, this
is a pointer, so the use of the asterisk
The asterisk ( ), from Late Latin , from Ancient Greek , , "little star", is a Typography, typographical symbol. It is so called because it resembles a conventional image of a star (heraldry), heraldic star.
Computer scientists and Mathematici ...
(*) is necessary to convert it into a reference to be returned.
See also
*Access modifiers
Access modifiers (or access specifiers) are keywords in object-oriented languages that set the accessibility of classes, methods, and other members. Access modifiers are a specific part of programming language syntax used to facilitate the e ...
* Virtual inheritance
*Class (computer programming)
In object-oriented programming, a class defines the shared aspects of objects created from the class. The capabilities of a class differ between programming languages, but generally the shared aspects consist of state ( variables) and behavior ( ...
*Class-based programming
Class-based programming, or more commonly class-orientation, is a style of object-oriented programming (OOP) in which inheritance (object-oriented programming), inheritance occurs via defining ''class (computer programming), classes'' of object ( ...
* Object composition
*Type conversion
In computer science, type conversion, type casting, type coercion, and type juggling are different ways of changing an expression from one data type to another. An example would be the conversion of an integer value into a floating point val ...
* final (C++)
References
General References:
Cplusplus.com tutorial lesson 5.2
, accessed in January 2006
, accessed in February 2006
{{DEFAULTSORT:C++ Classes
Articles with example C++ code
C++
Class (computer programming)