#c #class #derived-class
#c #класс #производный класс
Вопрос:
У меня есть это:
class foo {
public:
int a;
int b;
int c;
};
Это нормально, но я хочу добавить некоторую перегрузку оператора без изменения класса foo:
class bar: public foo {
operator==(const bar amp;x) const {
return a == x.a;
}
}
Пока все в порядке, но теперь мне нужно инициализировать bar массивом объектов, которые я получаю из другого класса. Нет проблем, я могу просто скопировать все переменные foo в bar в специальном конструкторе:
bar::bar(foo amp;x) {
a = foo.a;
/* etc */
}
Но это кажется запутанным, и если класс foo over обновляется, тогда мне тоже нужно обновить bar. Гораздо предпочтительнее, если бы bar мог автоматически инициализировать себя (он никогда не будет содержать свои собственные элементы данных)
Ответ №1:
разве это не так просто, как убедиться, что у Foo есть конструктор копирования…….
bar::bar(foo amp;x)
: foo(x)
{
}
class foo {
foo::foo(foo amp;x)
{
a = foo.a; /* etc */
}
};
Комментарии:
1.
foo
как указано в вопросе, уже имеет конструктор копирования по умолчанию. Вам не нужно ничего добавлять, просто вызовите это.2. Я прочитал это снова, и я не вижу, где говорится, что у Foo уже есть конструктор копирования. У меня создалось впечатление, что он напечатал все соответствующее определение класса для Foo в своем примере.
3. Если класс выглядит так, как в вопросе, компилятор сгенерирует для него конструктор копирования по умолчанию, выполняя копирование всех элементов по элементам.
Ответ №2:
Ну, просто:
bar::bar(const fooamp; x)
: foo(x)
{
}
Просто используйте foo
конструктор копирования. Все, что находится между :
и {
, называется списком инициализаторов. Вы можете напрямую инициализировать свои элементы и базовые классы там. Для foo
конструктор копирования может выглядеть следующим образом:
foo::foo(const fooamp; other)
: a(other.a)
, b(other.b)
, c(other.c)
{
}
Обратите внимание, что я принимаю оба аргумента по ссылке const, что является хорошей практикой, поскольку вы не касаетесь других объектов. Также обратите внимание, что в большинстве случаев нет необходимости писать конструктор копирования для foo
себя, только когда ваш класс содержит необработанные указатели ( int*
например). Компилятор сам сгенерирует ctor для копирования, если вы его не определите, а просто создадите поверхностную копию всех элементов данных.
Ответ №3:
Наследование конструкторов невозможно выполнить в C 03, но может быть приближено. Добавьте эти конструкторы:
template<class T1> bar(const T1amp; x1) : foo(x1) {}
template<class T1, class T2> bar(const T1amp; x1, const T2amp; x2) : foo(x1, x2) {}
template<class T1, class T2, class T3> bar(const T1amp; x1, const T2amp; x2, const T3amp; x3) : foo(x1, x2, x3) {}
// as much as you need...
В C 0x используется конструктор с одним шаблоном и совершенной пересылкой.
Комментарии:
1. Да ? Если вы просто хотите, чтобы производный класс можно было инициализировать из базового класса, это, несомненно, возможно в C 03.
2. @Xeo: копирование инициализировано — возможно. Наследовать конструкторы — невозможно. Просто попробуйте расширить
vector
с помощью нового метода и посмотрите, в чем проблемы…3. В любом случае, по-видимому, это не совсем то, чего хотела операционная система… (хотя это тоже решает его / ее проблему).