Breaking down large .cpp files into smaller chunks - suggestions?


As I work on more complicated modules, my strategy of putting all a module’s code in one big file is causing me headaches. It’s time consuming to jump around in large .cpp files and I often find myself losing my place. It’s probably bad practice as well.

My instinct is to move all widgets and and other structs into a folder, like so:

DigitalSequencer [folder]
  - Sequencer.cpp  (contains Struct Sequencer code)
  - VoltageSequencer.cpp
  - GateSequencer.cpp
  - DigitalSequencerDisplay.cpp (widget code)
  - DigitalSequencerPatternDisplay.cpp
  - etc...

I could also create a “Shared” folder for code shared between modules.

Does this sound sane?


You could organize your classes in header-only files. For example,

  • plugin.cpp depends on
    • MyModuleWidget.hpp depends on
      • MyModule.hpp depends on
        • MyModuleEngine.hpp
      • MyModuleDisplay.hpp depends on
        • MyModulePatternWidget.hpp

plugin.cpp could contain the Model global. Each header would depend on plugin.hpp, which includes rack.hpp and other “common” classes shared across your plugin.

1 Like

Probably make more sense to put them in Header Files and #include them in plugin.hpp. Depending on the namespacing of course. For instance you would not want to be using namespace std; in a header file (if you have a function with the same name as an std function it will cause ambiguity) instead std::...

That sounds good. I’ll try putting them in header files. :slight_smile: Thanks for the suggestions. I’m going to try Andrew’s strategy and see how it feels.

It will take a while to find what works for you. In my experience it’s quite “normal” to only put declarations into .h files and try to make them small and readable, and put as much as possible into a separate cpp file. But it all works.

As you indicated you will want to share stuff between modules. I would say I have very little code that only goes in one module? Except of course the Modules and ModuleWidgets themselves.

But, again, it’s going to come down to what works for you.

Not a intensive programmer these days but had a valuable lesson or three on this:

  1. don’t called it shared unless it is truly utilities for every module, otherwise you may as well call it “junk drawer”

  2. figure out a name for the existing class (hopefully the class name actually means something) that is doing too much and find the code that doesn’t really belong in the class

  3. figure out a name for the new class

  4. there is pretty much no step 4, now you are just shuffling lines of code from one class to the other and is made fairly easy by having the right names in place

I don’t get this. What if it’s junk that’s in only two or three modules? You should copy and paste it rather than sharing it?

I mean it is easy to label it shared but then only use it in one class or makes it tempting to put a bunch of smaller things that don’t really go together In there. No I’m not suggesting you repeat yourself. All I really meant I guess was “names matter”

1 Like

Might be known already but as an aside:

When using either be sure to use the proper access modifiers public: or private: when sharing is required. The access modifiers are the only difference between struct and class.

by default: struct is public, class is private. Unless specified


if I have time I try to work on a plugin (and somehow currently I have plenty of time :thinking:). You can take a look at it here - and see how it is structured. This should be the proper way of C++ programming in these days in my opinion .

It is by far not finished, as I spent a lot of time for making this testable with unit tests, setting up CI, code coverage etc. But because of this I think it is easy to understand in this state.