Я бы предложил использовать метод 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();
}
То есть вместо того, чтобы один конструктор вызывал другой, оба вызывают частного друга!