Note 4 Operator Overloading

Source: Internet
Author: User
Tags class operator
One operator overload
1 Definition of the string class:
# Include <iostream>
Class string;
Istream & operator> (istream &, string &);
Ostream & operator <(ostream &, const string &);

Class string {
Public:
// Overload set of the constructor
String (const char * = 0 );
String (const string &)

~ String ();

String & operator = (const string &); // copy the value assignment operator
String & operator = (const string *);

Char & operator [] (INT) const;

Bool operator = (const char *) const;
Bool operator = (const string &) const;

Int size ()
{
Return _ size;
}

Char * c_str ()
{
Return _ string;
}

PRIVATE:
Int size;
Char * _ string;
}

# Include <cstring>
Inline string & string: Operator + = (const string & RHs)
{
If (RHS. _ string)
{
String TMP (* This );
_ SIZE + = RHS. _ size;
_ String = new char (_ SIZE + 1 );
Strcpy (_ string, TMP, string );
Strcpy (_ string + TMP. _ size, RHS. _ string );
}
Return * this;
}

Differences between the copy constructor and the copy value assignment operator
Class S
{
};
S S1;
S S1 = S2; // S1 has called its own default constructor before calling the copy value assignment operator.

=, [], (), And-> operators must be defined as class member operators. Any definition that defines these operators as namespace members will be marked as a compilation error.

Other operators cannot be defined for built-in data types.

Program The operator can only define overload operators for class or enumeration type operands. We can declare the overload operator as a class member or namespace member, with at least one class or enumeration type parameter. The <> operator of a custom class is defined as a global function rather than a member function, because the left operand of the two operators is stream rather than a custom class. Binary youyuan defines equal operators of the string class as global functions: bool operator = (const string & str1, const string & str2 ){ If (str1.size ()! = Str2.size () // Private Members of the type cannot be directly referenced and must be referenced indirectly. Return false; Return strcmp (STR, c_str (), str2.c _ STR ())? False; ture;} is defined as a member function: bool operator = (const string & RHs) const { If (_ size! = RHS. _ SIZE) // Private Members of the type can be directly referenced. Return false; Return strcmp (_ string, RHS. _ string )? False; true;} another possible implementation is to declare the global equals operator as a friend of the string class by declaring the function or operator as friend, A class can grant this function or operator the right to access its non-public members. The friend Declaration starts with the keyword "friend" and can only appear in the class definition. Because youyuan is not a member of the authorization class, it is not affected by the declared region (public, private, and protected) of its class. Class string { Friend bool operator = (const string &, const string &); Friend bool operator = (const char *, const string &); Friend bool operator = (const char *, const char *); Public: Other parts ........} 2. If a function is used to manipulate two objects of different classes and the function needs to access non-public members of these two classes, then this function can be declared as the Friends of these two classes or as a member function of one class and declared as the Friends of another class. Operator 3 = string & string: Operator = (const char * sobj ){ If (! Sobj) { _ Size = 0; Delete [] _ string; _ String = 0; } Else { _ Size = strlen (sobj ); Delete [] _ string; _ String = new char [_ SIZE + 1]; Strcpy (_ string, sobj ); } Return * This;} _ string references the copy of the C-style string pointed to by the sobj parameter. _ String = sobj; // Type Mismatch sobj is a pointer to const. A pointer to const cannot be assigned a pointer to a non-Const. _ String points to an array of characters allocated in the heap. To prevent memory leakage, the C-style string originally referenced by _ string is released through the delete expression before _ string points to the memory allocated to save the new string value. Because _ string points to a character array, you must use the array version of the delete expression. Four operators () # include <vector> # include <algorithm> int main (){ Int Ia [] = {0, 1,-2, 3, 5,-5, 8 }; Vector <int> ivec (IA, Ia + 8 ); Transform (ivec. Begin (), ivec. End (), ivec. Begin (), absint ()); //...................} The first and second real parameters of transform () are only the range of elements applied by the absint operation. The third real parameter points to the fourth parameter of transform (), which is a temporary object of the absint class. It is created by calling the default constructor of the absint class. Generic called by main () Algorithm Transform (), which looks like the following: typedef vector <int>: iterator iter_type; iter_type transform (iter_type ITER, iter_type last, iter_type result, absint func ){ While (ITER! = Last) * Result ++ = func (* ITER ++ ); Return ITER;} five operators-> WE can reload the member access operator arrow for class objects. It must be defined as a member function of a class, it is used to assign a behavior similar to a pointer to a class type. It is usually used for a class type that represents "smart pointer. That is to say, the behavior of a class is similar to the built-in pointer type. Class screenptr {public: Screenptr (screen & S): PTR (& S ){} //... Private: Screen * PTR;}; the initial value must be provided for the definition of screenptr objects. For a screen object, the screenptr object points to it. Otherwise, the definition of the screenptr object is incorrect: Screenptr P1; // Error Screen myscreen (4, 4 ); Screenptr PS (myscreen); // OK in order to make the screenptr class behave like a built-in pointer, we must define some overload operators, unreference operators (*) and member access operators (->) class screenptr {public: Screenptr (screen & S): PTR (& S ){} Screen & operator * () {return * PTR ;} Screen & operator-> () {return PTR ;} //... Private: Screen * PTR;}; the returned type of the reloaded member access operator arrow must be a class pointer or an object that defines the class of the member access operator arrow. If the returned type is a pointer of the class type, the arrow of the built-in member access operator is applied to the return value. If the returned value is an object or reference of another class, the process is applied recursively and the pointer or statement error is returned. Of course, the pointer to this type of manipulating class object is not as efficient as using the built-in pointer type. Therefore, the smart pointer class must provide other functions that are important to our program design to offset the additional overhead produced by using it. The six operators ++ and -- we first define a new data member called size. It contains 0 (indicating that the screenptr object points to a single object) or the size of the array referred to by the screenptr object. Define a data member called offset to record the offset in the array indicated by the screenptr object: Class screenptr {public ://... PRIVATE: int size; // array size for a single object, the value of which is 0int offset; // the offset of the PTR in the array screen * PTR;}; Class screenptr {public: Screenptr (screen & S, int arraysize = 0) : PTR (& S), size (arraysize), offset (0) {} PRIVATE: Int size; Int offset; Screen * PTR;}; the declaration of the prefix operator looks like the class screenptr {public: Screen & operator ++ (); Screen & operator --(); //...}; To differentiate post-operator and pre-operator declarations, the declaration of the overload increment and decrement postoperator has an additional int type parameter. Class screenptr {public: Screen & operator ++ (); // prefix Operator Screen & operator --(); Screen & operator ++ (INT); // Post Operator Screen & operator-(INT ); //...}; The overloaded increment and decrement operators can also be declared as friend functions. For example, we can change the definition of screenptr and declare these operators as friend functions. The following shows the class screenptr {// non-member declaration. Friend screen & operator ++ (screenptr &); // front Friend screen & operator--(screenptr &); Friend screen & operator ++ (screenptr &, INT); // post Friend screen & operator--(screenptr &, INT); public: // Member definition}; the return type of the New and delete member operators new () must be void * type and have a size_t type parameter, size_t is a typedef defined in the system header file <cstddef>. Class Screen {public: void * operator new (size_t );//...}; when a new expression creates an object of the class type, the compiler checks whether the class has a member operator new (). If yes, select this operator to allocate memory for the class object; otherwise, call the global operator new (). For example, the new expression below Screen * PS = new screen; a screen object is created in the free storage area. Because the screen class has a member operator new (), this member operator new () is called () the size_t parameter of the operator is automatically initialized to the size of the screen class. Programmers can use the fully-local resolution operator to choose to call the global operator new () such as screen * PS =: new screen member operator Delete () the return type of must be void and the first parameter type is void *. Class Screen {public: void operator Delete (void *) ;}; Delete pS; released the memory of the screen class object referred to by PS because the screen class has the member operator Delete (), therefore, the delete () operator is called, and the void * parameter of the operator is automatically initialized to the PS value. The new () and delete () operators are static members of the class. They comply with the general limitations of static member functions. Static member functions do not have the this pointer, so they can only access static data members. The reason is that these operators are called either before the class object is created [operator new ()] or after it is destroyed [operator Delete ()] We can also declare the operators new [] () and delete [] () for Array allocation as class members. The return type of the class member operator new [] () must be void * and the first parameter type is size_t. The return type of the member operator Delete [] () must be void. Its first parameter must be void *. For example, the following is the screen operator Delete [] (). declare class screen {public: void operator Delete [] (void *) ;}; create an array of new expressions first call the class operator new [] () to allocate the storage area, then, call the default constructor to initialize each element of the array in sequence. If constructor is defined but no default constructor exists, the corresponding new expression is incorrect. Because no C ++ syntax can specify an initial value for the array element, or specify real parameters for the class constructor in the new expression of the array version.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.