Технически, вы можете определить конструктор копирования DataModel
, взяв ссылку ComputationalModel
в качестве параметра функции.
DataModel d1(/* Parameter... */);
ComputationModel c1(/* Parameter... */);
DataModel d2(d1); // copy-construct instance, d1 passed as refence to the base class
DataModel d3(c1); // same behavior
Это, однако, почти никогда не будет хорошей идеей, потому что для копирования объекта обычно требуется состояние объекта для копирования. Когда вы передаете ссылку на базовый класс, вы удаляете все члены-данные экземпляра производного класса, что оставляет вновь созданный объект в состоянии, которое трудно угадать из клиентского кода.
Конструктор копирования по умолчанию имеет квалифицированный константный аргумент ссылки на точно такой же тип, в вашем случае:
DataModel(const DataModel& other) = default;
что подводит меня к вашему последнему вопросу
Почему конструктора копирования по умолчанию здесь недостаточно?
Это трудно сказать, не видя остальную часть вашей иерархии наследования. Рекомендуется следующее: если конструктор копирования всех элементов данных в иерархии делает правильные вещи, то и конструктор копирования по умолчанию также делает правильные вещи.