в train.py:
PARAMS = {
'train_dataset_path': '/mnt/datasets/imagenet/train_shards/',
'val_dataset_path': '/mnt/datasets/imagenet/val_shards/',
}
изменить путь набора данных
К сожалению, виртуальный шаблон клона/копии является Вашим единственным реальным выбором.
Существуют изменения этого, но по существу они все сводятся к записи функций для каждого типа, который может возвратить новую копию.
Я не думаю, что было бы легко сделать. На самом деле, в Эффективном C++, Meyers предупредил, что, если у Вас есть функция, которую говорит передача значением, и Вы имеете
void foo(Base b)
и Вы передаете a Derived1 d1
в foo
, копия была бы отрезана - т.е. полученные части не будут скопированы.
Но затем я заключаю в кавычки из памяти в данный момент...
Необходимо реализовать виртуальный метод клона на каждом объекте в иерархии. Как еще был бы Ваш объект неопределенного типа знать, как скопировать себя?
Для создания этого более очевидным для людей, пишущих производные классы, Вы могли бы думать о создании краткого обзора метода клона в Вашем базовом классе также, вынуждать людей, по крайней мере, записать что-то.
В нескольких местах для моего кода я также тестирую, чтобы удостовериться, что to_string () метод реализован правильно для сериализации объекта к строке. Определенный тест, что я раньше в моем классе тестировал клон и to_string одновременно, похож на это:
Base *obj1, *obj2;
# initialize obj1 in a reasonable manner
obj2 = obj1->clone();
assert( obj1->to_string() == obj2->to_string() );
Это тестирует обоих метод клона () и сериализация объекта к строкам (таким образом, это не строго модульный тест), но это - парадигма, настолько простая переноситься в цикле вокруг всех объектов на фабрике, чтобы удостовериться, что они следуют за некоторым минимальным стандартом реализации клона () и to_string ().
Править: Обновленный код с исправлением из комментария strager. Спасибо!
Конструктор копии не возможен (насколько я знаю), потому что память выделяется, прежде чем конструктора вызывают. Конструктор копии известного типа используется, не типа объекта.
Base *foo = new Derived1();
Base bar = *foo; // Base's copy constructor is called.
Ваш лучший выбор состоял бы в том, чтобы обеспечить a clone()
метод, как Вы предположили.
Если Вы хотите прозрачный метод клона, изучаете Неявное Совместное использование.
Вы корректны о clone()
. Вы не можете использовать конструкторов, потому что они вызывают статическое связывание. Вы не можете возвратить объект значением, потому что это снова вызывает статическое связывание. Таким образом Вам нужна виртуальная функция, которая возвращает динамично выделенный объект.
Альтернатива должна создать подобное фабрике Base
, принятие Вас знает все Ваши производные классы:
Вообще-то, если задуматься это - вероятно, плохая идея!
class Base {
public:
static Base *clone(const Base *obj) {
if((Derived1 *o = dynamic_cast<Derived1 *>(obj)) {
return new Derived1(*o);
} else if((Derived2 *o = dynamic_cast<Derived2 *>(obj)) {
return new Derived2(*o);
}
/* TODO When more classes are added, put them here. (Probably bad design, yes.) */
return new Base(obj);
}
Base *clone() const {
return clone(this);
}
};