-2

I am working on a data parser for a project. I have to parse a file that may contain two different types of objects:

Type-1: sb0 hardrectilinear 4 (0, 0) (0, 82) (199, 82) (199, 0)

Type-1 has to be stored as a class block, with the following attributes: BlockID, BlockType, number_of_edges, lowerleft, lowerright, upperleft, upperright.

Type-2: sb1 softrectangular 24045 0.300 3.000

Type-2 also has to be stored as a class block, with the following attributes: BlockID, BlockType, area, min_aspectRatio, max_aspectRatio.

Is it possible to build a single class called "block", with a different set of arguments depending on the attribute "BlockType"? I have built a parser but I used two different classes for each BlockType using sstream.

I have shown my implementation of the parser when the text file to be parsed contains only type-2. Any ideas on how I can do this using a single class?

SoftBlock.h:

#ifndef SOFTBLOCKLIST_H_
#define SOFTBLOCKLIST_H_
#include <string>
#include <vector>
#include "SoftBlock.h"
#include <fstream>


class SoftBlockList {
public:
    SoftBlockList(std::string input_file);

    std::vector<SoftBlock> get_softblocklist();

private:
    std::vector<SoftBlock> softblocklist;

};

#endif /* SOFTBLOCKLIST_H_ */

SoftBlock.cpp:

#include "SoftBlockList.h"
using namespace std;

SoftBlockList::SoftBlockList(string input_file) {
    ifstream filehandle;
    filehandle.open(input_file.c_str());
    string temp;
    while(filehandle.good()){
        getline(filehandle, temp);
        SoftBlock block(temp);
        softblocklist.push_back(block);
    }
    filehandle.close();
}

vector<SoftBlock> SoftBlockList::get_softblocklist(){return 
softblocklist;}
  • what does "class block" mean? please provide some code that shows what you want to achieve. – Stephan Lechner Oct 21 '17 at 20:43
  • Sounds like maybe a use-case for a template. – Jesper Juhl Oct 21 '17 at 20:43
  • I meant a class called block. I have edited the question. Basically, the parser has to parse the above two different types of line into a single class called "block". But depending on the attribute "BlockType", it has to have different attributes. – Vignesh Shriram Oct 21 '17 at 20:49
  • What’s the purpose of the class? Which functions will it contain? – Tob Oct 21 '17 at 20:54
  • It sounds to me like you are being asked to use some inheritance. You’ll have a base class (possibly abstract), and two specialized/dependent classes (HardRectilinear and SoftRectangular). When you read the keyword (is “sb0” part of the file? or “hardrectilinear”? or what?) then you create and populate the appropriate subclass. You’ll need a collection of pointers to the base class. – Dúthomhas Oct 21 '17 at 21:07

1 Answers1

0

A simple way to do this would be to use a union. The union can only have 1 active member at a time, and only occupies a size equal to the biggest member.

#include <iostream>
using namespace std;

class Block {
    public:
    struct Type1 {
        int number_of_edges;
        float lowerleft, lowerright, upperleft, upperright;
    };
    struct Type2 {
        double area;
        float min_aspectRatio, max_aspectRatio;
    };

    union combinedData {
        Type1 t1;
        Type2 t2;
    };

    int BlockID;
    int BlockType;

    combinedData data;
};

int main() {
    Block block;
    block.BlockType = 1;
    block.data.t1.number_of_edges = 1; // Type1 is now active
    cout << block.data.t1.number_of_edges << endl;
    block.BlockType = 2;
    block.data.t2.area = 1.5678; // Switched to Type2 being the active member
    cout << block.data.t2.area << endl;
}

You can then use the value of BlockType to determine which member is active.

super
  • 12,335
  • 2
  • 19
  • 29