struct Song {
Lyrics lyr_;
Rhythm rhy_;
Image img_;
Notes notes_;
string filename_;
};
Don't use global variables. Instead add data to an isolated context-- a repository of information a code module might need, allowing few arguments and decoupled code. Show me your flowcharts and conceal your tables, and I shall continue to be mystified. Show me your tables, and I won't usually need your flowcharts; they'll be obvious.[ The Mythical Man Month]
Bad programmers worry about the code. Good programmers worry about data structures and their relationships.[Linus Torvalds: https://lwn.net/Articles/193245/]
void apply(const Context&);
A read-only context. If your code can use this, it absolutely should. Downstream users and coders can't accidentally change something with bugs or misunderstandings.struct DataHeader { // pod
uint id;
int numTimes;
doub radius;
};
struct Data {
DataHeader header;
vector<Trombones*> trombones;
void copy(Data*dest) {
memcpy(&dest->header, &header, sizeof(DataHeader));
dest->trombones.resize(trombones.size());
for (sz_t i=0; i<trombones.size(); ++i)
dest->trombones[i] = trombones[i];
}
};
"Plain old data" can be handled in fast, useful ways that aren't generally ok. Factoring out the pod sub-context lets you take advantage of that systematically.struct SongAppendix {
Metadata metadata;
vector<Song*> similar;
vector<Link*> links;
};
struct Song {
Lyrics lyr_;
Rhythm rhy_;
Image img_;
Notes notes_;
string filename_;
SongAppendix apdx;
};
Factoring out optional additions keeps the core idea clear. nedwaves.com 2017 [171108]