Class 4.1 (Classes)
Class is a logical way to organize data and functions in the same structure. The definition class is class, and its functionality is similar to a struct in C, except that class can contain functions, unlike structs that can only contain data elements.
The class definition is in the form of:
Class Class_name { permission_label_1: member1; Permission_label_2: member2; ... } object_name;
Where Class_name is the name of the class (the user-defined type), and the optional object_name is one or more objects (object) identifiers. The declaration body of class contains member members, which can be data or function definitions, and can include the Allow range flag permission labels, which can be any of the following three keywords: private:, Public: OR Protected:. They represent the following meanings, respectively:
- Private members of Private:class, only the other members of the same class or the class's "Friend" class can access these members.
- Protected:class's protected member, only the other members of the same class, or the class's "Friend" class, or the class's subclass (derived classes) can access these members.
- The public members of Public:class can access these members anywhere they can see the class.
Constructors and destructors (constructors and destructors)
Objects (object) often need to initialize variables or allocate dynamic memory during the build process, so that we can operate, or prevent unexpected results from being returned during execution. For example, in the previous example, what would happen if we called the function area () before calling the function Set_values ()? May be an indeterminate value because member X and Y have not yet been assigned to any value.
To prevent this from happening, a class can contain a special function: constructor constructor, which can be defined by declaring a function with the same name as class. This constructor is automatically called when and only if you want to generate a new instance of Class (instance), that is, when you declare a new object, or allocate memory to an object of that class.
析构函数Destructor 完成相反的功能。它在objects被从内存中释放的时候被自动调用。释放可能是因为它存在的范围已经结束了(例如,如果object被定义为一个函数内的本地(local)对象变量,而该函数结束了);或者是因为它是一个动态分配的对象,而被使用操作符delete释放
Constructor overloading (overloading constructors)
Like other functions, a constructor can be overloaded multiple times (overload) as a function of the same name, but with different parameter types and numbers. Remember that the compiler invokes the same function (Section 2.3, FUNCTIONS-II) as the parameter type and number required at the time of the call. Here is the constructor that is called when the class object is declared.
In fact, when we define a class without a definite definition of the constructor, the compiler automatically assumes two overloaded constructors (the default constructor, "constructor" and the copy constructor "copy constructor"). For example, for the following class:
Class Cexample {public : int a,b,c; void multiply (int n, int m) {a=n; b=m; c=a*b;}; };
Without a constructor defined, the compiler automatically assumes that it has the following constructor member functions:
- Empty Constructor
It is a constructor without any parameters and is defined as NOP (no statement). It doesn't do anything.
CExample::CExample () { };
- Copy Constructor
It is a constructor that has only one parameter, which is an object of this class, and the function is to copy the values of all non-static (non-static) member variables of the object being passed in to this object itself.
Cexample::cexample (const cexample& RV) { a=rv.a; B=RV.B; c=rv.c; }
必须注意:这两个默认构造函数(empty construction 和 copy constructor )只有在没有其它构造函数被明确定义的情况下才存在。如果任何其它有任意参数的构造函数被定义了,这两个构造函数就都不存在了。在这种情况下,如果你想要有empty construction 和 copy constructor ,就必需要自己定义它们。
当然,如果你也可以重载class的构造函数,定义有不同的参数或完全没有参数的构造函数,见如下例子:
//overloading class constructors #include <iostream.h> class Crectan gle {int width, height; Public:crectangle (); Crectangle (Int,int); int area (void) {return (width*height);} }; Crectangle::crectangle () {width = 5; Height = 5; } crectangle::crectangle (int a, int b) {width = A; height = b; } int main () {Crectangle rect (3,4); Crectangle RECTB; cout << "rect area:" << rect.area () << Endl; cout << "RECTB area:" << rectb.area () << Endl; } |
rect area:12 RECTB area:25 |
在上面的例子中,rectb 被声明的时候没有参数,所以它被使用没有参数的构造函数进行初始化,也就是width 和height 都被赋值为5。
注意在我们声明一个新的object的时候,如果不想传入参数,则不需要写括号():
CRectangle rectb; // right
CRectangle rectb(); // wrong!
Pointer to class (pointers to classes)
Classes can also have pointers, and to define pointers to classes, we just need to realize that once a class is defined it becomes a valid data type, so only the name of the class can be used as the name of the pointer. For example:
CRectangle * prect;
is a pointer to an object of class Crectangle type.
Just like in the case of a data organization, you need to use the operator---to directly refer to a member in an object that is pointed to by a pointer. Here is an example that shows several possible scenarios:
//pointer to classes example #include <iostream.h> cla SS Crectangle {int width, height; Public:void set_values (int, int); int area (void) {return (width * height);} }; void Crectangle::set_values (int a, int b) {width = A; height = b; } int main () {Crectangle A, *b, *c; Crectangle * d = new crectangle[2]; b= new Crectangle; C= &a; (a.set_values); B->set_values (3,4); D->set_values (5,6); D[1].set_values (7,8); cout << "A area:" << a.area () << Endl; cout << "*b area:" << b->area () << Endl; cout << "*c area:" << c->area () << Endl; cout << "d[0" area: "<< d[0].area () << Endl; cout << "d[1" area: "<< d[1].area () << Endl; return 0; }
|
A area:2 *b Area:12 *c Area:2 D[0] Area:30 D[1] Area:56 |
Here is how to read some pointers and class operators (*, &,.,->, []) that appear in the previous example:
- *x read: Pointed by X (pointed by X)
- &X read: Address of X (Addresses of X)
- X.Y read as: member Y of Object X (member y of object X)
- (*x). Y reads: member Y of object pointed by X (member y of the object pointed by X)
- X->y read: Member Y of object pointed by X (same previous equivalent)
- X[0] Read: First object pointed by X (the object that is pointed to by X)
- X[1] Read: Second object pointed by X (second object pointed by X)
- X[n] read: (n+1) th object pointed by X (the N+1 object pointed by X)
Classes defined by the keyword struct and union
Classes can be defined not only by the keyword class, but also by a struct or union.
Because the concepts of classes and data structures are too similar in C + +, the two-keyword struct and class function almost the same (that is, classes defined in C + + can have member functions, not just data members). The only difference between classes defined by class is that the default access rights for all members of classes defined by class are private, and the default access rights for all members of a struct-defined class are public. In addition, two keywords are the same.
The concept of union differs from the class defined by struct and class, because Union can store only one data member at a time. However, classes defined by Union can also have member functions. The class access permissions defined by union are default to public.
4.2 Operator overloading (overloading operators)
C + + implements the use of language standard operators between classes (class), not just between basic data types. For example:
int a, b, c;
a = b + c;
is a valid operation because the variables on both sides of the plus sign are basic data types. However, whether we can do the following is not so obvious (it is actually correct):
struct { char product [50]; float price; } a, b, c;
a = b + c;
It is permissible to assign an object of class (or struct struct) to another object of the same type (by using the default copy constructor, copy constructor). But the additive operation is likely to produce an error, which in theory is not valid between non-basic data types.
But thanks to the C + + operator overloading (overload) capability, we can do this. Objects of the combined type, such as those in the example above, can be accepted in C + + without operator overloading, and we can even modify the effect of these operators. The following is a list of all the operators that can be overloaded:
+ - * / = < > + = *= /= << >><<= >>= = = = <= >= + + -- % & ^ ! | ~ &= ^= |= && | | %= [] () new Delete
To overload an operator, we just need to write a member function named operator, followed by the operator we want to overload, following the prototype definition:
type operator sign (parameters);
Here is an example of an operator +. We want to calculate the two-dimensional vector (bidimensional vector) A (3,1) and B (.) and. The addition of two-dimensional vectors is simply the addition of the two x-axis values to the x-axis value of the result, and the addition of the two y-axis values to obtain the Y-value of the result. In this example, the result is (3+1,1+2) = (4,3).
//Vectors:overloading Operators Example #include <iostream.h> class Cvector {public : int x, y; Cvector () {}; Cvector (int,int); Cvector operator + (cvector); }; Cvector::cvector (int A, int b) { x = A; y = b; } Cvector cvector::operator+ (cvector param) { cvector temp; temp.x = x + param.x; Temp.y = y + param.y; return (temp); } int main () { cvector a (3,1); Cvector b (in); Cvector C; c = a + B; cout << c.x << "," << c.y; return 0; } |
4,3 |
If you're confused about why you see so many cvector, it's because some of them refer to class name Cvector, and others are name of the function named after it, don't confuse them:
Cvector (int, int); //Function name Cvector (constructor) Cvector operator+ (cvector); //function operator+ Returns the value of the Cvector type
The function operator+ of Class Cvector is the function that overloads the math operator +. This function can be invoked in the following two ways:
c = a + b;
c = a.operator+ (b);
Note: we include an empty constructor (no arguments) in this example, and we define it as nothing:
CVector ( ) { };
This is necessary because there is already another constructor in the example,
CVector (int, int);
Therefore, if we do not explicitly define one as above, none of the two default constructors for Cvector exist.
In this case, the statement contained in main ()
CVector c;
will be illegal.
Nonetheless, I have warned that an empty statement block (No-op block) is not a recommended implementation of a constructor because it does not implement a basic function that a constructor should at least complete, that is, initialize all the variables in class. In our example, this constructor does not complete the definition of the variable x and Y. So a more recommendable constructor definition should look like this:
CVector ( ) { x=0; y=0; };
Just like a class default contains an empty constructor and a copy constructor, it contains a default definition for the assignment operator assignation operator (=), which is used between two homogeneous objects. This operator copies all non-static (non-static) data members of its parameter object (the object to the right of the symbol) to the object to its left. Of course, you can also redefine it as any feature you want, such as copying only certain class members.
Overloading an operator does not require maintaining its regular mathematical meaning, although this is recommended. For example, although we can define the operator + to take the difference of two objects, or to assign an object to 0 with the = = operator, there is no logical meaning to do so.
Although the prototype definition of the function operator+ looks obvious, because it takes the object on the right side of the operator as the parameter of the function operator+ the left object, the other operators are not necessarily so obvious. The following list summarizes how different operator functions define declarations (replace each @ with an operator):
Expression |
Operator (@) |
function member |
Global Function |
@a |
+-* &! ~ +-- |
a::[email protected] () |
[email protected] (a |
[email protected] |
+-- |
a::[email protected] (int) |
[em Ail protected] (A, int) |
[email protected] |
+-*/% ^ & | < > = = = <= >= << >> && | | , |
a::[email protected] (B) |
[email protected] (A, B) |
[Email prot Ected] |
= + = = *=/=%= ^= &= |= <<= >>= [] |
a::[email protected] (B) |
- |
A (b, c ...) |
() |
a::operator () (B, C ...) |
- |
a->b |
-> |
a::operator-> () |
- |
* Here A is an object of Class A, B is an object of B, and C is an object of Class C.
As you can see from the table above, there are two ways to overload some class operators: as member functions (member function) or as global functions. There is no difference in their usage, but I would like to remind you that if you are not a member of class, you cannot access the private or protected members of the class unless the whole domain function is a friend of that class (the meaning of friend will be explained in later chapters).
Keyword this
The keyword this is usually used inside a class, which is the address of the object in memory in which the class is being executed. It is a pointer whose value is always the address of its own object.
It can be used to check whether the arguments passed into the member function of an object are the object itself. For example:
// this #include <iostream.h> class Cdummy {public : int isitme (cdummy& param); }; int cdummy::isitme (cdummy& param) { if (¶m = = this) return 1; else return 0; } int main () { cdummy A; cdummy* B = &a; if (B->isitme (a)) cout << "Yes, &a is B"; return 0; } |
Yes, &a is b |
It is also often used in member function operator= to return pointers to objects (avoid using temporary objects). Here's a look at how the function operator= is implemented using the vector example shown earlier:
cvector& cvector::operator= (const cvector& param) { x=param.x; Y=PARAM.Y; return *this; }
In fact, if we don't define the member function operator=, the compiler automatically generates the default code for that class, which is probably what it looks like.
Static members
A class can contain static members, which can be data or functions.
A class static data member is also referred to as the class variable "class variables" because their content does not depend on an object and has the same value for all objects of the same class.
For example, it can be used to calculate the number of objects for a class declaration, as shown in the following code program:
//static members in classes #include <iostream.h> class Cdummy {public : static int n; Cdummy () {n++;}; ~cdummy () {n--;}; }; int cdummy::n=0; int main () { cdummy A; Cdummy b[5]; Cdummy * c = new Cdummy; cout << a.n << Endl; Delete C; cout << cdummy::n << Endl; return 0; |
7 6 |
In fact, a static member has the same properties as a global variable variable, but it has a range of classes (class). Therefore, according to the ansi-c++ standard, in order to avoid them being repeated repeatedly, in class declaration can only include the static member prototype (declaration), and can not include its definition (initialization operation). To initialize a static data member, we have to include a formal definition outside of class (at the global scope), as in the example above.
Because it is the same value for all objects of the same class, it can be referenced either as a member of any object of that class, or directly as a member of class (this only applies to static members, of course):
cout << a.n;
cout << CDummy::n;
All two of these calls refer to the same variable: the static variable N in class Cdummy.
At the time of the reminder, it is actually a whole domain variable. The only difference is that its name is followed by the class.
Just as we would include static data in class, we can also make it include the static function. They represent the same meaning: the static function is a global functions function, but is called as an object member of a specified class. They can only reference static data and never refer to class's non-static (nonstatic) members. They are also not able to use the keyword this because this actually refers to an object pointer, but these static functions are not members of any object, but are direct members of class.
C + + Review in mind (2)----fwqlzz love are for ever