Although the code in your question isn't very clear, my understanding is that you are proposing to create an object from some input data. You outline two options:
Make loading the data a public method. There are few upsides to this beyond convenience. It's a pretty clear violation of the Single Responsibility Principle and it couples the model's in-memory representation to its on-disk representation. This isn't usually a very good thing. It also potentially leaves your model in an invalid state after creation, which is also very error-prone. It is much better to have classes that are never in invalid states whenever possible. A slight improvement would be to make this a static member function, rather than an instance method.
Pass an existing instance to a separate loader. This is a somewhat better approach if, again, your model object has no invalid states. And if your model has no invalid states, then it should be trivial to initialize a default-constructed one inside the function, rather than taking a reference as a parameter.
The best solution, then, is the adjustment I mentioned in (2). Design your model so that a default-constructed instance is valid, and then write a method in your Lexer
(perhaps renamed to "ModelLoader" or "Parser" since it is doing more than lexing) to load a file from disk and populate a fresh Model
instance, and then return it. In modern C++, guaranteed return value optimization (RVO) should alleviate any concerns you might have with returning a large object.
Ideally, your loader/deserializer would also take an input stream of some sort, rather than a filename directly. Qt's QDataStream
, for example, can abstract over several different media (drives, network, in-memory buffers, etc.)
If you need (or want) your Model
to be immutable, then you can employ the Builder pattern to stage updates to a Model
before actually constructing it.