C++学习系列五:Classes(I)||uniform initialixzation||Pointers||struct||union

  • Classes(I)

    Classes are an expanded concept of data structures : like data structures, they can contain data members, but they can also contain funcitons as members.

    An object is an instantiation of a class. In terms of variables, a class would be the type, and an object would be the variable.

    After the declarations of 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:

    • private

      members of a class are accessible only from within other members of the same class

    • protected

      members are accessible from other members of the same class (or from their “friends”), but also form members of their derived classes

    • public

      members are accessible from anywhere where the object is visible

    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`.  
  • Uniform Initialization

    The way of calling constructors by enclosing their arguments in parentheses, as shown above, is known as functional form. But constructors can also be called with other syntaxes:

    • First, constructors with a single parameter can be called using the variable initialization syntax (an equal sign followed by the argument)

      class_name object_name = initialization_value;
      
    • More recently, C++ introduced the possibility of consructors to be called using uniform initialization, which essentially is the same as the functional form, but using braces ({}) instead of parentheses ( () ):

      class_name object_name {value, value, value, ...}
      

      Optionally, this last syntax can include an equal sign before the braces.

      // classes and uniform initialization
      #include <iostream>
      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() << '\n';
          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.

  • Member initialization in constructors

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.

  • Pointers to classes

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 defined with struct and union

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.

猜你喜欢

转载自blog.csdn.net/The_Time_Runner/article/details/107304711