Access members of a derived class using a C ++ base class pointer

Is there a way to have a shared access code for members of a derived class through a base class pointer? Or in any other way?

Say I have a Shape class. I have Square and Triangle classes that inherit it. Both have their own private members that have nothing to do with each other, so it makes no sense to have them in the base class. Now, if I need to write a class to a file, but I don’t know if the class is a square or a triangle until when I need to write it to a file?

I tried to figure out how to solve this problem. The worst solution would be to write both the square and the triangle data to a file, add an identifier (triangle or square) for reading and writing, and have a small parser to combine the class when loading data. This would be an inefficient and empty time.

I was wondering if there was any trick or design pattern or anything that could help in the situation.

+4
source share
5 answers

This serialization must be performed using virtual functions. Define a function in the base class that should serialize the object. Triangle and square override these functions and write

  • identifier
  • all data to be serialized

If necessary, you can implement the common part of the base class.

If you want to upload a file, you will need a factory method that creates an instance of the class corresponding to the identifier. To load the actual data, you must call the virtual deserialization method of the new instance.

+8
source

You may have a pure virtual getter in the base class. and all your derived classes override this. like this

class Shape{ public: virtual int data() const = 0; }; class Square: public Shape{ private: int _member; public: virtual int data() const{ //do something with private members and return it return _member; }; }; 
+3
source

I think there is no direct way to remove this overhead. This is usually done in two ways. First of all, an object needs a serialization mechanism:

To serialize things, you need a place to serialize. In this case, we will do this using a data container, but it can also be a file stream or a container class. Serialization can be performed inside the object or from the outside, the simplest implementation now occurs from the inside:

The simple part of serialization:

 class Shape{ public: virtual void serialize( Datacontainer &o ) const = 0; }; class Triangle: public Shape{ void serialize( Datacontainer &o ) const{ o.add('T'); o.add(corners); } std::vector<point> corners; } class Circle: public Shape{ void serialize( Datacontainer &o ) const{ o.add('C'); o.add(center); o.add(radius); } point center; double radius; } 

During serialization, you can do this using the base Shape class:

 Shape *tri = new Triangle; tri->serialize( dataContainer or file ); 

Deserialization is not so simple because you need to know the type. A good example for this is the Builder pattern. Despite this, we can implement a more likely C ++ method:

Add the following to all your classes:

 static Shape* createFrom( Datacontainer &o ); 

For example, the implementation of Circle:

 Shape* Circle::createFrom( Datacontainer &o ) { Circle *c = new Circle() c->center = o.get(); c->radius = o.get(); } 

This allows us to create a specific instance, but we have a common functional trace for the method. Now you can implement a very simple builder like this:

 class ShapeBuilder { public: static Shape* createShape( Datacontainer& o ) { char id = o.get(); swith(id){ case 'T': return Triangle::createFrom(o); case 'C': return Circle::createFrom(o); } } } 
+1
source

You need to declare virtual methods in your base class and define derived classes. If you want to save them to a file, you will need a way to determine which instance of the class is in the file, since they can have different memory layouts.

0
source

Probably the best way is to do something like this. The main patten is that you can put a common code that is guaranteed to always be the same for each derived class in the database. Insert things that should be different into a virtual function that derived classes implement differently.

 class Shape { virtual void writeSerialData(std::ostream &) const = 0; public: void writeToFile(const std::string &filename) const { std::ofstream outfile(filename); // filename.c_str() in C++03 writeSerialData(outfile); if (!outfile.close()) { // report the error } } virtual ~Shape() {} }; class Square : public Shape { double length; virtual void writeSerialData(std::ostream &out) const { out << "Square{" << length << '}'; } public: Square(double l) : length(l) {} }; 

Now you have the following problem: how do you read an object from a file without knowing in advance which derived class it is? To do this, you need a way to see the Square text and either (a) call a static function of the Square class that knows how to interpret the data, or (b) create an instance of the Square class, providing it with data to interpret, Before you go too far on this Ways to look at Serialization Acceleration or other serialization libraries.

0
source

Source: https://habr.com/ru/post/1432289/


All Articles