Сделайте копию неизвестного конкретного типа в C++

в train.py:

PARAMS = {
    'train_dataset_path': '/mnt/datasets/imagenet/train_shards/',
    'val_dataset_path': '/mnt/datasets/imagenet/val_shards/',

}

изменить путь набора данных

5
задан Martin Beckett 27 January 2009 в 02:38
поделиться

7 ответов

К сожалению, виртуальный шаблон клона/копии является Вашим единственным реальным выбором.

Существуют изменения этого, но по существу они все сводятся к записи функций для каждого типа, который может возвратить новую копию.

13
ответ дан 18 December 2019 в 09:10
поделиться

Я не думаю, что было бы легко сделать. На самом деле, в Эффективном C++, Meyers предупредил, что, если у Вас есть функция, которую говорит передача значением, и Вы имеете

void foo(Base b)

и Вы передаете a Derived1 d1 в foo, копия была бы отрезана - т.е. полученные части не будут скопированы.

Но затем я заключаю в кавычки из памяти в данный момент...

2
ответ дан 18 December 2019 в 09:10
поделиться

Необходимо реализовать виртуальный метод клона на каждом объекте в иерархии. Как еще был бы Ваш объект неопределенного типа знать, как скопировать себя?

Для создания этого более очевидным для людей, пишущих производные классы, Вы могли бы думать о создании краткого обзора метода клона в Вашем базовом классе также, вынуждать людей, по крайней мере, записать что-то.

В нескольких местах для моего кода я также тестирую, чтобы удостовериться, что 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. Спасибо!

4
ответ дан 18 December 2019 в 09:10
поделиться

Конструктор копии не возможен (насколько я знаю), потому что память выделяется, прежде чем конструктора вызывают. Конструктор копии известного типа используется, не типа объекта.

Base *foo = new Derived1();
Base bar = *foo;               // Base's copy constructor is called.

Ваш лучший выбор состоял бы в том, чтобы обеспечить a clone() метод, как Вы предположили.

0
ответ дан 18 December 2019 в 09:10
поделиться

Если Вы хотите прозрачный метод клона, изучаете Неявное Совместное использование.

0
ответ дан 18 December 2019 в 09:10
поделиться

Вы корректны о clone(). Вы не можете использовать конструкторов, потому что они вызывают статическое связывание. Вы не можете возвратить объект значением, потому что это снова вызывает статическое связывание. Таким образом Вам нужна виртуальная функция, которая возвращает динамично выделенный объект.

0
ответ дан 18 December 2019 в 09:10
поделиться

Альтернатива должна создать подобное фабрике 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);
        }
};
-1
ответ дан 18 December 2019 в 09:10
поделиться
Другие вопросы по тегам:

Похожие вопросы: