当前位置:网站首页>OOP multiple storage (class template)

OOP multiple storage (class template)

2022-06-23 01:04:00 SZU healing system bug

Catalog

Title Description

Thought analysis

AC Code


Title Description

Now we're going to make a box , It can accommodate many types of elements , such as int、double、char、string wait .

Every time we receive a piece of data, we wrap it in this kind of box , And put it in the same vector in .

In order to be able to wrap different types of elements , We decided to use template classes to implement this box , And named it CBox.

However , We noticed that CBox<int>、CBox<char> And other classes are defined from the same template class , But they are actually incompatible types .

In order to be able to put a vector in , We decided to do something for CBox The template class defines an abstract parent class CBoxObject.

In this way, we can use the parent class pointer to put different CBox The instance class objects are concentrated in one vector<CBoxObject*> China .

Here's how CBoxObject The definition of an abstract class :( Do not modify the )

class CBoxObject {

protected:

    string type; // Record type information

public:

    CBoxObject(string _type) : type(_type) {}

    virtual void show(ostream&) const = 0; // Used to output information

};

To see vector Data of any box in , We decided to use polymorphic technology to achieve :

1. requirement CBox Template class inheritance CBoxObject class , And define a member variable ;

2. CBox To implement a superclass virtual function void show(ostream&),show The function outputs information to ostream in ,

   1) The general output format is :{type: value}

   2) If the element is a null pointer , The output of :{}

3. by CBox Add template class void setVal(T _val) function , In order to modify the data

The main test functions are as follows :( Do not modify the )

template<typename T>

void pushBox(istream& in, vector<CBoxObject*>& container, const string& type) {

    T val;

    in >> val;

    container.emplace_back(new CBox<T>(type, val));

}

int main() {

    string type; // data type

    int n, index; // n Enter the number of times ,index by vector The array subscript

    cin >> n;

    vector<CBoxObject*> pBoxes;

    pBoxes.reserve(n); // Allocate enough space in advance (pBoxes.size()==0 Still established )

    while (n-- > 0) {

        cin >> type;

        // Package according to the data type

        if (type == "char") pushBox<char>(cin, pBoxes, type);

        else if (type == "int") pushBox<int>(cin, pBoxes, type);

        else if (type == "double") pushBox<double>(cin, pBoxes, type);

        else if (type == "string") pushBox<string>(cin, pBoxes, type);

        // We think one box can also be used to pack another box

        // For convenience , We use box pointers to represent the packaging relationship between boxes

        else if (type == "box") {

            cin >> index;

            auto box = new CBox<CBoxObject*>("box", nullptr);

            // according to index from pBoxes Choose one of the existing boxes and pack it in a new box

            if (0 <= index && index < pBoxes.size()) {

                box->setVal(pBoxes[index]);

                // In reality, the box can't pack itself

                // In the subject , If the box packs itself , Set the pointer value to null

                // For the time being, the problem of linked list forming a ring will not be considered

            }

            pBoxes.emplace_back(box);            

        }

        index = (int)pBoxes.size() - 1;

        cout << *pBoxes[index] << endl;

    }

    for (CBoxObject*& box : pBoxes) delete box;

    return 0;

}

In the decision to use CBoxObject* The native pointer type is used as CBox Template parameters for , You may find a problem :

a) If the value of the package is " Null pointer nullptr"(NULL Not really ), Then there will be problems in the output !

b) If the wrapper value is a non null pointer , In general, there is no value in printing pointer values , We are more concerned with what the pointer points to .

We hope to be able to T* Such template parameter types define different processing methods .

Through further study, we can learn c++ Supported by " Template specialization " Method :

template<typename T> class CC { ...... };

template<typename T> class CC<T*> { ...... };

template<typename T> class CC<const T*> { ...... };

......

4.  by CBox Template class definitions are suitable for specialized versions with native pointers as template parameters

    Because the defined member variable is of pointer type , And the same object is new It may be given to multiple owners when it comes out ,

    To simplify programming , Destructors are not considered in this problem ( Use the default )

( To further ensure the security of replication and destruction , Avoid memory leaks , Consider joining " Reference count pointer " Further refine the definition , There is no requirement for this topic )

    The specialized version of this question is :

   template <>

   class CBox<CBoxObject *> :public CBoxObject

   {

       CBoxObject *data;

When processing output , You might write "cout<<val;" and "cout<<*val;" Such a statement can be used in general int*,string* And other native pointers

If used CBox<T*>, Please note that the corresponding T Class should have an output overload

5. by CBoxObject Class overloaded output

Input

See main function

Output

Output format :{type: value}

If value Null pointer (nullptr), The output of :{}

sample input 1

sample output 1

Thought analysis

First of all, you should see that it uses the standard template library STL Of vector, We want to include vector file .

Then we need to specialize for pointer types , Don't let it call generic templates , Write another .

AC Code

ostream& operator<<(ostream& out, CBoxObject& box) {
	box.show(out);
	return out;
}
ostream& operator<<(ostream& out, CBoxObject* box) {
	box->show(out);
	return out;
}
template<class T>
class CBox: public CBoxObject {
	protected:
		T value;
	public:
		CBox(string type, T value): CBoxObject(type), value(value) {}
		virtual void show(ostream& out)	const{
			out << '{' << type << ": " << value << '}';
		}
		void setVal(T _val) {
			value = _val;
		}
};
template<> 
class CBox<CBoxObject*>: public CBoxObject {
	protected:
		CBoxObject* value;
	public:
		CBox(string type, CBoxObject* value): CBoxObject(type), value(value) {}
		virtual void show(ostream& out)	const{
			if(value)
			out << '{' << type << ": " << value << '}';
			else out<<"{}";
		}
		void setVal(CBoxObject* _val) {
			value = _val;
		}
};
原网站

版权声明
本文为[SZU healing system bug]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/173/202206221409100301.html