简体   繁体   中英

How would I separate this class?

I'm learning computer graphics and OpenGL, and I load models from my own binary format with a JSON manifest file to keep track of the assets.

The Model class I have right now keeps track of the OpenGL objects necessary to draw it with, as well as handling the processing of the 3D model files:

class Model
{
public:
    Model(const std::string &filename);
    // read the manifest
    // load the appropriate binary files
    // finally make the OpenGL objects this class keeps track of

    // ... etc, like draw()
private:
    // handles for various OpenGL objects
}

I would like to separate the file processing from the bookkeeping of OpenGL graphics stuff as I feel like that's too much responsibility for a single class. How would I go about doing that?

I thought about making a ModelLoader class, but I don't think there's any state that needs keeping track of in order to load this. So maybe I should make it a function inside a ModelLoader namespace. I played around with it but ended up with:

// ModelLoader.hpp
#include "Model.hpp"

namespace ModelLoader
{
    Model load(const std::string &filename);
}

// ModelLoader.cpp
#include "ModelLoader.hpp"

Model ModelLoader::load()
{
    return Model();
}

// Model.hpp
class Model;

namespace ModelLoader
{
    Model load();
};

class Model
{
    friend Model ModelLoader::load();
public:
    // ... etc, like draw()
private:
    Model(const std::string &filename); // accessible only through ModelLoader::load()
    // handles for various OpenGL objects
}

There was a circular dependency between Model and ModelLoader , and what I have up there was the only way I could get it to compile. But as you can see, that kind of defeats the purpose of the declarations inside ModelLoader.hpp , plus it's duplicated code. I'm still not too good with C++ and object oriented design. Should I just go with what I had before? If I really wanted to separate file loading from bookkeeping, how should I do it? What's wrong with my attempts?

I'd recommend a slightly different approach. Make your class know how to serialize and deserialize itself from a stream.

That way you can use string streams, file streams, network streams, etc.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM