C ++ - базовый класс клонирования - PullRequest
1 голос
/ 21 сентября 2009

У меня что-то подобное:

Class Foo : Base {.."my stuph" ..};

int main() {
   Base *b = new Base;
   Foo  f (b);   <== **error** "invalid conversion from Base to Foo."
  ..
}

Как я могу клонировать b в f?
В «Моей штуке» у меня есть функции, которые делают тренировки между Foo и Base.
Я не могу сильно изменить Base, пока она написана другими.

Спасибо

Ответы [ 5 ]

5 голосов
/ 21 сентября 2009

Вы не можете автоматически сделать производный класс из базового. Однако вы можете сделать наоборот и создать базовый класс из производного, и это может сбить вас с толку.

Чтобы сделать то, что вы хотите, вы должны добавить правильный конструктор к Foo и подумать, как вы на самом деле создадите информацию, отсутствующую в экземпляре Base, чтобы создать полнофункциональный экземпляр Foo.

Конструктор может выглядеть так:

Foo(Base const& b) : Base(b)
{ /* construct info specific to Foo (absent in Bar) */ }
4 голосов
/ 21 сентября 2009

Определить конструктор, который принимает аргумент типа Base:

Foo(const Base & b)
: Base(b) // construct the base class, using its copy constructor
{
    // plus, initialize Foo-specific member data here
}

Кстати: вы уверены, что хотите, чтобы Base был частным базовым классом?

1 голос
/ 21 сентября 2009

Операция клонирования - это операция, которая предоставляет точную копию объекта. Преобразование Base в Foo не является операцией клонирования.

В вашем вопросе class пишется с заглавной буквы 'C', Foo происходит от Base, его члены (важные для этого вопроса) не отображаются, Base b = new Base не будет компилироваться, и я понятия не имею, что означает «тренировка между Foo и Base». Пожалуйста, найдите время, чтобы создать правильный пример, который показывает (только) проблему, с которой вы столкнулись, и дает точное описание того, что вы видите и чего ожидаете. С таким вопросом, как он есть, я не уверен, с чего начать, что ты сделал не так. Я предлагаю вам изменить свой вопрос, чтобы показать некоторый код, который компилируется (за исключением проблемы, которая у вас есть).

Тогда я мог бы отредактировать этот ответ так, чтобы он объяснил, что происходит.

1 голос
/ 21 сентября 2009

Дайте Foo конструктор, который принимает параметр Base:

class Foo : public Base {
public:
    explicit Foo(const Base &b) {
        // do work to initialise Foo. You might want to include
        Base::operator=(b);
        // or you might not. Depends how Foo works, and what Base's
        // constructors do.
    }
};

Всякий раз, когда вы пишете конструктор с одним аргументом, вы должны подумать, хотите ли вы указать "явный".

«Явный» означает, что конструктор должен использоваться только там, где вы явно написали вызов конструктора или приведение. Если его там нет, то компилятор также «неявно» преобразует объекты Base в Foo, например, в следующей ситуации:

int doSomething(const Foo &f) {
    return 23;
}

Base b;
doSomething(b); // doesn't compile
doSomething(static_cast<Foo>(b)); // does compile

Если вы удалите «явное», то doSomething(b) скомпилирует и сделает то же самое, что и вторая строка - создаст временный объект Foo из b и передаст его doSomething.

1 голос
/ 21 сентября 2009

Предоставляет конструктор, который принимает базовый класс или ссылку на него.

...