C++学習シリーズ5:Classes(I)||uniform initialixzation||Pointers||struct||union
Rectangle
and rect
, any of the public members of object rect
can be accessed as if they were normal functions or normal variables, by simply inserting a dot (.) between object name and member name. This follows the same syntax as accessing the members of plain data structures. The operator of scope (::)
is used to specify that the function being defined is a member of the class and not a regualr non-member function. The most important property of a class is that it is a type
, and as such, we can declare multiple objects
of it. Classes allow programming using object-oriented paradigms. Classes are defined using either keyword class
or keyword struct
, with the following syntax: class class_name {
access_specifier_1:
member1;
access_specifier_2;
member2;
...
} object_names;
Where class_name
is a valid identifier for the class
, object_names
is an optional list of names for objects of this class. The body of the declaration can contain members, which can either be data or function declarations, and opetianlly access specifiers. Classes have the same format as plain data structures, except that they can also include functions
and have these new things called access specifiers
. An access specifier is one of the following three keywords: By default, all members of a class declared with the
class
keyword have private access for all its members. Therefore, any member that is declared before any other access specifier has private access automatically. For example: class Rectangle {
int width, height;
public:
void set_values (int, int);
int area(void);
} rect;
Declares a *class* (i.e., a type) called `Rectangle` and an *object* (i.e., a variable) of this class, called `rect`. This class contains four members: two data members of type `int` (member `width` and member `height`) with *private access* (because *private* is the default access level) and two member functions with *public access*: the functions `set_values` and `area`, of which for now we have only included their *declaration*, but not their *definiton*.
Notice the difference between the *class name* and the object name: In the previous example , Rectangle was the class name (i.e., the type), whereas `rect` was an object of type `Rectangle`.
class_name object_name = initialization_value;
class_name object_name {value, value, value, ...}
Optionally, this last syntax can include an equal
sign before the braces. // classes and uniform initialization
#include
using namespace std;
class Circle {
double radius;
public:
Circle (double r) {radius = r;}
double circum() {return 2*radius*3.14159265;}
};
int main() {
Circle foo (10); //functional form
Circle bar = 20; // assignment init
Circle baz {30}; // uniform init
Circle qux = {40}; // POD-like
cout << "foo's circumference: " << foo.circum() << '
';
return 0;
}
An advantage of uniform initialization over functional form is that, unlike parentheses, braces cannot be confused with function declarations, and thus can be used to explicitly call default constructors: Rectangle rectb; // default constructor called
Rectangle rectc(); // function declaration (default constructor NOT called)
Rectangle rectd{}; //default constructor called
The choice of syntax to call constructors is largely a matter of style. Most existing code currently uses functional form, and some newer style guides suggest to choose uniform initialization over the others, even though it also has its potential pitfalls for its preference of initializer_list as its type. When a constructor is used to initialize other members, these other members can be initialized directly, without resorting to statements in its body. This is done by inserting, before the constructor’s body, a colon (
:
) and a list of initializations for class members. For example, consider a class with the following declaration: class Rectangle {
int width, height;
public:
Rectangle (int, int);
int area() {return width*height;}
};
Rectangle::Rectangle (int x, int y) {width=x; height=y;}
// is equal to
Rectangle::Rectangle (int x, int y) : width(x) {height=y;} // member initialization
// is equal to
Rectangle::Rectangle (int x, int y) : width(x), height(y) {}
In the last case, the constructor does nothing else than
initialize
its members, hence it has an empty function body. For members of fundamental types, it makes no difference which of the ways above the constructor is defined, because they are not initialized by default, but for member objects (those whose type is a class), if they are not initialized after the colon, they are
default-constructed
. Objects can also be pointed to by pointers: Once declared, a class becomes a valid type, so it can be used as the type pointed to by a pointer. For example:
Rectangle * prect;
is a pointer to an object of class
Rectangle
. Similarly as with plain data structures, the members of an object can be accessed directly from a pointer by using the arrow operator (->)
. Several operators to operate on objects and pointers (operatores *
, &
, .
, ->
, []
), they can be interpreted as : Expression
Can be read as
*x
pointed to by
x
(pointer) &x
address to
x
(variable) x.y
member
y
of object x
x->y
member
y
of object pointed to by x
(pointer), arrow operator (->) (*x).y
member
y
of object pointed to by x
(equivalent to the previous one) x[0]
first object pointed to by
x
x[1]
second object pointed to by
x
x[n]
(n+1)th object pointed to by
x
, offset operator [] Classes can be defined not only with keyword
class
, but also with keyword struct
and union
. The keyword
struct
, generally used to declare plain data structures, can also be used to declare classes that have member functions, with the same syntax as with keyword class
. The only difference between both is that members of classes declared with the keyword struct
have public access by default, while members of classes declared with the keyword class
have private access by default. For all other purposes both keywords are equivalent in this context. Conversely, the concept of
unions
is different from that of classes declared with struct
and class
, since unions only store one data member at a time, but nevertheless they are also classes and thus also hold member functions. The default access in union
classes is public.