C ++ Shen Shuographic note (Surrogate, using class to express concept)

xiaoxiao2021-03-06  13

Object-oriented four features: abstraction, inheritance, packaging and polymorphism.

When writing a program, we often solve different types of functions of different types (packaged) but related to each other (inheritance). Sharing inheritance and encapsulation, forcing us to handle two issues, control memory allocation, and put different types of objects into the same package.

For example, this example is mentioned in the book: parking_lot - parking; Vehicle - Various vehicles in the parking lot;

Class Vehicle {public: Virtual Double Weight () const = 0; Virtual Void Start () = 0;};

Class RoadVehi: Public Vehicle {/ * ... * /}; Class Autovehi: Public RoadVehi {/ * ... * /}; Class Aircraft: Public Vehicle {/ * ... * /}; Class Helicopter: Public Aircraft {/ * ... * / }

Here Parking_lot cannot be implemented in an array, as member functions weight () and start () are pure virtual functions, and the class VEHICLE itself does not have an object, and there is no object array.

But even if there is a Vehicle object (exclude all the pure virtual functions in the type VEHICLE), if you write similar to the following statement: Automobile X = / * ... * / parking_lot [NUM_VEHICLES ] = X; It is obvious, parking_lot is just a VEHICLES Collection.

How to solve these two problems, there are two methods: 1. Provide an Indirection. Suitable indirection form is to store pointers, such as: Vehicle * parking_lot [100]; parking_lot [NUM_VEHICLES ] = New Automobile (x); 2. Using a class called Surrogate by the author, each object of this class represents another object, which can be an object located in a complete inheritance hierarchy.

The first is in the form of Indirection, but this approach is less than 2 points: 1. Brought the burden of dynamic memory management 2. This method can only be used when the object in the parking_lot is a static type. Otherwise, it is not possible to ensure that this program will not be wrong. Assume that parking_lot [P] points to a new VEHICLE whose type and value are the same as the object pointing to the parking_lot [q]. Both of the following methods are erroneous // parkint_lot [p] and parkint_lot [q] will point to the same object. IF (p! = Q) {delete parking_lot [P]; parking_lot [P] = parking_lot [q];} // There is no Vehicle type object, even if there are, not what we want! IF (p! = Q) {delete parking_lot [p]; parking_lot [p] = new vehicle (parking_lot [q]);}

Then use Surrogate. This is a class to indicate the concept, Koenig and Moo use this as the basic C design principle.

Define a surrogate, behavior, and Vehicle objects, and potentially represent all things that inherit the object of the Vehicle class. In this way, copying surrogate will copy its corresponding VEHICLE object, and the new object will be deleted first, then copy the new object. Dagbruck pointed out that this processing method is slightly different from what we expect, because this way has changed the type of object actually associated with the proxy class on the left.

There are several ways to pay attention to: 1. Cannot be default constructed. Because if Vehicle is an abstract base class, we cannot specify the default operation of VEHICLESUROGATE and the type of object it points to. It is impossible to be class Vehicle, because there is no Vehicle object at all. Introducing behavior concepts for Empty Surrogate in empty pointers. It is possible to create, destroy and copy such surrogate, but other operations are considered an error. 2. Each time the call to COPY is a virtual call, it can only be virtual. 3. It is necessary to copy the V.vp non-zero detection in the confidue operator, otherwise call V, VP-> COPY will be wrong 4. To detect the assignment operator, make sure that the agent is not assigned to itself. 5. Let the Surrogate class support other operations that the class VEHICLE can support. However, these functions are not virtual due to the Surrogate class does not inherit the object from the class. 6. These functions themselves can call virtual functions in the corresponding VEHICLE object. They should also check to ensure that VP is not zero

The following is a problem solving: class vehicle {public: Virtual double weight () const = 0; Virtual void start () = 0; Virtual Vehicle * copy () const = 0; virtual ~ vehicle () {} // Process one After the object, you need to clear the object. // ......};

Class RoadVehi: Public Vehicle {/ * ... * /}; Class Autovehi: Public RoadVehi {/ * ... * /};

Vehicle * Autovehi :: Copy () const {return new autovehi (* this);

Class Vehiclesurrogate {public: // This will create an array of VEHICLESURROGATE objects; Empty Surrogate Vehiclesurrogate (): vp (0) {}; // To create a proxy for objects that can inherit the class from Vehicle; EMPTY Surrogate Vehiclesurrogate Const Vehicle &): VP (v.copy ()) {}; ~ vehiclesurrogate (); vehiclesurrogate (const vehicles); vehiclesurrogate & operator = (const vehiclesurrogate); private: vehicle * vp;};

Vehiclesurrogate :: Vehiclesurrogate (const vehiclesurrogate): vp (v.vp? V.vp-> copy (): c) {}

VEHICLESURROGATE :: ~ VEHICLESURROGATE () {delete vp;} Vehiclesurrogate & operator = (const vehiclesurrogate &) {f (this! = & V) {delete vp; vp = v.vp? V.vp-> copy (): 0);} Return * this;} Double Vehiclesurrogate :: Weight () const {if (vp == 0) throw "EMPTY VEHICLESURROGATE.WEIGHT ()" Return VP-> weight ();

Void Vehiclesurrogate :: Start () {if (vp == 0) throw "Empty Vehicles ".Start ()"; VP-> Start ();} Parking (parking_lot) can be defined: VEHICLESURROGATE PARKING_LOT [1000]; Autovehi X; parking_lot [Num_Vehicles ] = x;

March 16, 2005

转载请注明原文地址:https://www.9cbs.com/read-46939.html

New Post(0)