Я бы предложил использовать метод private friend
, который реализует логику приложения конструктора и вызывается различными конструкторами. Вот пример:
Предположим, у нас есть класс с именем StreamArrayReader
с некоторыми частными полями:
private:
istream * in;
// More private fields
И мы хотим определить два конструктора:
public:
StreamArrayReader(istream * in_stream);
StreamArrayReader(char * filepath);
// More constructors...
Где второй просто использует первый (и, конечно, мы не хотим дублировать реализацию первого). В идеале хотелось бы сделать что-то вроде:
StreamArrayReader::StreamArrayReader(istream * in_stream){
// Implementation
}
StreamArrayReader::StreamArrayReader(char * filepath) {
ifstream instream;
instream.open(filepath);
StreamArrayReader(&instream);
instream.close();
}
Однако в C ++ это запрещено. По этой причине мы можем определить метод частного друга следующим образом, который реализует то, что должен делать первый конструктор:
private:
friend void init_stream_array_reader(StreamArrayReader *o, istream * is);
Теперь этот метод (потому что он друг) имеет доступ к закрытым полям o
. Тогда первый конструктор станет:
StreamArrayReader::StreamArrayReader(istream * is) {
init_stream_array_reader(this, is);
}
Обратите внимание, что при этом не создается несколько копий для вновь созданных копий. Второй становится:
StreamArrayReader::StreamArrayReader(char * filepath) {
ifstream instream;
instream.open(filepath);
init_stream_array_reader(this, &instream);
instream.close();
}
То есть вместо того, чтобы один конструктор вызывал другой, оба вызывают частного друга!
Использование
this
ИЛИauto
в указанном контексте было бы интересными ключевыми словами для целей будущего рефакторинга.