More effective C + + terms of proxy classes (alias class, proxy class)

Source: Internet
Author: User

1. The so-called proxy class, refers to "each of its objects are for other objects exist, like other objects of the agent general." In some cases, replacing some built-in type with a proxy class allows for unique functionality. Because a member function can be defined for a proxy class, it cannot be defined on a built-in type. Article 5 shows an example of using a proxy class to block implicit type conversions.

2. Implement a two-dimensional array.

C + + does not provide syntax for assigning dynamic two-dimensional arrays, so it is often necessary to define classes (templates implement these functions), like this:

template<class t>class  array2d {public:    array2d (int  int  dim2);    ...};
View Code

Since it is a two-dimensional array, it is necessary to provide an operation that uses "[]" to access the element, whereas [[] is not an operator, C + + does not allow overloading a operator[][], the workaround is to use the proxy class, like this:

template<classT>classArray2D { Public:    //proxy class    classarray1d { Public: T&operator[](intindex); Constt&operator[](intIndexConst;    ...    }; ARRAY1Doperator[](intindex); Constarray1doperator[](intIndexConst; ...};
View Code

Then the following actions:

array2d<float> data (<< data[3] [6];
View Code

DATA[3][6] actually made two function calls: the first call to Array2D's operator[], returned the ARRAY1D object, and the second call to ARRAY1D operator[], returning the specified element.

(This example of the role of proxy class is not significant, because the pointer can be applied operator[], so long as the Array2D oeprator[] return a pointer can achieve the same effect, there is no need to use the proxy class)

3. Read and write actions that distinguish operator[]

Clause 29 discusses the reference count in the case of the string class, as it is not possible to determine whether the characters returned by Non-const version oeprator[] will be used for read or write operations, so for insurance, once the Non-const version operator[] is invoked, Creates a new piece of memory and copies the data structure to the new memory. Under this strategy, if the characters returned by operator[] are used for read operations, then the behavior of allocating new memory and copying the data structure is unnecessary, resulting in a loss of efficiency, using a proxy Class can differentiate between Non-const operator[] for read or write operations, like this:

classString { Public:    //the proxy class is used to distinguish between read and write operations of operator[]    classCharproxy {//proxies for string chars     Public: Charproxy (String& STR,intindex);//Creationcharproxy&operator=(Constcharproxy& RHS);//Lvaluecharproxy&operator=(Charc);//uses        operator Char()Const; Private: String& TheString;//used to manipulate a string and to open new memory at the appropriate time and replicate        intCharIndex;    }; ConstCharproxyoperator[](intIndexConst;//For Const StringsCharproxyoperator[](intindex);//For Non-const Strings.. friendclassCharproxy;Private: Rcptr<StringValue> value;//See clause};
View Code

Calling operator[] on string will return the Charproxy object, charproxy the behavior of the char type by overloading Oeprator char, but it is more advantageous than the char type--you can define a new operation for Charproxy, This way, when you use operator= with Charproxy, you can learn to write to Charproxy, and because Charproxy holds a reference to the parent object string, you can now execute the behavior of opening up memory and copying the data structure, like this:

string::charproxy& String::charproxy::operator=(Constcharproxy&RHS) {    if(thestring.value->isShared ()) {Thestring.value=NewStringValue (thestring.value->data); } thestring.value->data[charindex] = rhs.thestring.value->Data[rhs.charindex]; return* This;} String::charproxy& String::charproxy::operator=(Charc) {    if(thestring.value->isShared ()) {Thestring.value=NewStringValue (thestring.value->data); } thestring.value->data[charindex] =C; return* This;}//The code part of the function above is duplicated, consider extracting the repeating part into a function
View Code

Because of the memory opening and assignment of data structures to Charproxy, the string operator[] is quite simple, like this:

Const String::charproxy String::operator[] (intconst{    return charproxy (Const_cast<string&> (*this), index);} String::charproxy String::operator[] (int  index) {    return Charproxy (*this, index);}
View Code

The other parts of the Charproxy implementation are as follows:

int index): thestring (str), CharIndex (index) {}string::charproxy::operatorCharconst  {return thestring.value->data[charindex];}
View Code

4. Limitations.

Just as smart pointers never completely replace built-in pointers, the proxy class can never imitate all the features of built-in types. The proxy class does not function as a built-in type, but has pros and cons-it also has a lot of "patches" to emulate other features of built-in types.

1). Take the proxy class to the address.

Clause 29 Indicates whether an object can be shared to prevent tampering of the external pointer by adding a shareable flag (flag) to the StringValue class, which involves taking a operator[] return value, which prompts Charproxy to operator& To overload, like this:

class String {public:    class  charproxy {    public:        ...         Char operator&();         Const Char operator Const ;        ...    };    ...};
View Code

The const version operator& implementation is easier:

Const Char * string::charproxy::operatorconst{    return & ( Thestring.value->Data[charindex]);}
View Code

Non-const version of operator& to do more things:

Char * string::charproxy::operator&() {    // If shared memory is being used, Opens new memory and copies the data structure    if (thestring.value->isShared ())        {new stringvalue ( thestring.value->data);    }     // because there is an external pointer pointing to it, there is a risk of tampering and the use of shared memory    is forbidden Thestring.value->markunshareable ();     return & (thestring.value->data[charindex]);}
View Code

2). Pass the proxy class to the function that accepts "references to Non-const objects".

Suppose there is a swap function for the contents of the object two char:

void swap (charchar& B);

You will not be able to pass the Charproxy parameter to swap because the swap parameter is Char&, although Charproxy can be converted to char, but because the scratch char is a temporary object, it still cannot be bound to char& The workaround seems to be to overload the swap only.

3). Invoke the member function of the real object via proxy cobjects.

If the proxy class is intended to replace the built-in type, it must also overload the operations that the built-in type can perform, such as ++,+=, if it is used to replace the class type, it must also have the same member function. The ability to perform operations on such types can also be performed on the proxy class.

4). implicit type conversion.

The proxy class should have the same behavior as the proxy type, and the usual practice is to overload the implicit conversion operator, as in clause 5 for the use of the proxy class, the proxy class can take advantage of "user-defined implicit type conversion can not be implemented two consecutive times" Feature prevents unnecessary implicit type conversions, and the proxy class may also block implicit type conversions that are required by the user because of this feature.

5. Assessment

The role of proxy class is very powerful, like the above mentioned implementation of multidimensional arrays, distinguish operator[] read and write operations, suppress implicit type conversion, but also has its drawbacks, if the function returns a proxy class object, then it is a temporary object of zombies, It is possible to generate and destroy the additional structure and composition of this, and as 4 says, the proxy class cannot completely replace the behavior of the real object, although the operation of the real object can be done by the proxy class in most cases.

More effective C + + terms of proxy classes (alias class, proxy class)

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.