Вы говорите о двух разных видах кода: 1) размер исходного кода (который влияет только на время сборки) и 2) размер исполняемого файла (размер «скомпилированного кода» или сегмент кода). Они коррелированы, но определенно не совпадают.
Первая - сложная проблема, решаемая в C ++, потому что язык требует монолитных, автономных TU. (Сравните с таким языком, как Go, где дизайнеры научились избегать этой проблемы из своего опыта работы с Си.) Шаблоны справка, как и при использовании только прямых объявлений ("объявлений, которые не являются определениями ") когда вам не нужны определения. (Хотя иронично, что шаблоны помогают, так как на практике им требуется весь их код в заголовках.) В основном длительное время сборки - это то, с чем мы просто имеем дело с в текущем C ++.
Второе может быть смягчено либо с помощью общего метода инициализации, который может вызывать каждый ctor, либо с помощью общей базы. Последний имеет другие преимущества, например, когда инициализация членов может или должна быть сделана в списке инициализации. Пример:
struct SpanBase {
SpanBase(int start, int stop, int step)
: start(start), stop(stop), step(step)
// any complex code in the init list would normally be duplicated
// in each Span ctor
{
IMAGINE("complex code executed by each Span ctor");
if (start > stop) throw std::logic_error("Span: start exceeds stop");
}
protected:
int start, stop, step;
};
struct Span : protected SpanBase {
// Protected inheritance lets any class derived from Span access members
// which would be protected in Span if SpanBase didn't exist. If Span
// does not have any, then private inheritance can be used.
Span(int stop) : SpanBase(0, stop, 1) {}
Span(int start, int stop) : SpanBase(start, stop, 1) {}
Span(int start, int stop, int step): StepBase(start, stop, step) {}
// this one could be handled by a default value, but that's not always true
};
И, наконец, C ++ 0x позволяет вам делегировать от одного ctor к другому, поэтому весь этот шаблон значительно упрощен.