How would you design the data structure under this circumstance?

Suppose, I have point_c, line_c and block_c three classes:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
class point_c {
public:
    double x, y;
};

class line_c {
public:
    vector<point_c> Pt;

    void insertPoints();// insert points on line
};

class block_c {
public:
    vector<point_c> Pt;
    vector<line_c> Ln;

    void insertLines();
    void insertPoints();
};

As you can see, lines are composed of many points, and blocks are composed of lines and points. And I defined some member functions, so that I can add points or lines as required by line and block.

But, here comes the problem, if I use line.insertPoints(), or block.insertPoints(), the points will be stored in line or block. That is not what I want.

I want have a single place to store all points, a single place to store all lines, and a single place to store all blocks.

Then I guess I need some global variables

1
2
3
vector<point_c> Pt;
vector<line_c> Ln;
vector<block_c> Bk;


and I should change the classes into:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
class point_c {
public:
    double x, y;
};

class line_c {
public:
    vector<size_t> PtIndex;

    void insertPoints();// insert points on line
};

class block_c {
public:
    vector<size_t> PtIndex;
    vector<size_t> LnIndex;

    void insertLines();
    void insertPoints();
};


in this way, the member functions will create the real entities into the global vector and set an index pointing to that entity. But this approach just make me feel it is not OOP anymore. when people using these classes, they got be careful about the global variables.

So, the question is How would you guys do this? Thanks alot!
I have to ask, why do you want "a single place to store all points, [etc]"? What is your concern with having duplicate instances?

If you actually do need this strange restriction, then I would use the static factory pattern with the point class and have a private static std::set<point_c> and have it return a reference to the point you want. Then, in the containers, you would use reference wrappers, e.g. std::vector<std::reference_wrapper<point_c>>. You will need to disable copying and moving for the point class.
Last edited on
Because if I don't store them in a single place, then, when I make changes to points in lines and blocks, they won't change the really useful global points, they got their own copies, which need more memory and more operations to make them sync.
Memory should not be a concern unless you expect to process billions of points.

It sounds like you don't need global points at all, and you can just used shared_ptr or reference_wrapper. But, still, why do you want to be able to change the point from outside the container and have it affect the points inside the container? This is often considered a violation of encapsulation - you're changing the state of the container without the container's knowledge.

What was the original goal that you tried to solve and got you to this point? This seems like a mistake in initial design.
Thanks, I need to meshing the block, I will have many blocks to mesh, the blocks share boundary lines with each other, and so that also share points. Meshing will create tons of points. what I want outcome is a clean vector of points knowing whom their neighbor points are, and don't need to carry information about "in which line or block" anymore when finished. That is why.

Yes, the design is poor, how can I do it better?
Last edited on
Ah, I see now. So, you will always have the same set of points for related blocks - the blocks can just store iterators to the points in your std::set. Rather than points-in-object, you have object-from-points.
Last edited on
Thanks, LB, your method of using a set and reference looks interesting, I am not familiar with that syntax, could you please specify a little bit more? I mean how to write it for each class? and what is the advantage of using that instead of just put a index there. Thank you very much!
Last edited on
Sets don't have indexes, but they prevent duplicate objects. I just realized a complication with my design - sets don't let you change their elements. I suppose for what you want a vector of points is fine, but you would still use a set of iterators. I am working on an example, but I can't figure out how your line structure comes into play? Why does a block need to be composed of both lines and points?
Topic archived. No new replies allowed.