LINUX.ORG.RU

С++, запрет на использование функции родителя


0

0

Т.е. я хочу убедиться, что некая функция в классе-потомке обязательно была переопределена. Можно такое сделать?

например:


class Parent {
  public:
    virtual void f(); // эта функция обязательно должна быть преропределена!
    virtual void g();
    virtual void h(); // эта функция обязательно должна быть преропределена!
};

class Child : public Parent {
  public:
    virtual void f();
};

....

int main{}
{
  Child *c = new Child();
  c->f(); // это должно работать
  c->g(); // это должно работать
  c->h(); // а это вызывать ошибку компилляции
}

★★

С++, запрет на использование функции родителя

сделай её чисто виртуальной

jtootf ★★★★★ ()

С++, запрет на использование функции родителя

virtual void h() = 0;

lester ★★★★ ()

С++, запрет на использование функции родителя

Это-то понятно, но я хитрый и хочу создавать и объекты типа Parent тоже.

octy ★★ ()

Re: С++, запрет на использование функции родителя

Собственно я сделал Parent1 абстрактным, а наследование через промежуточного родителя Parent, но думал может я что-то не знаю.

octy ★★ ()

С++, запрет на использование функции родителя

class Base
{
public:
    virtual void f() {}
    virtual void g() {}
};

class IAux
{
private:
    virtual void g() = 0;
    virtual void f() = 0;
};

class Derived : public Base, IAux
{
public:
    virtual void g() {}
};

но это пятиногий конь, вообще говоря. правильный ответ такой, что ты не должен этого хотеть

jtootf ★★★★★ ()

Re: С++, запрет на использование функции родителя

Спасибо ) Но я просто хотел "если я в будущем буду наследовать от этого класса, то не забыть переопределить функцию f()"

Ну например в родителе есть массив переменных типа int, и функция в которой выделяется память для этого массива. Может оказаться, что в потомке массив будет переопределён с типом long, ну и память надо будет выделять в переопределённой функции. int и long - просто для примера, скорее в предке будет массив типа A, а в потомке - массив из потомоков A.

octy ★★ ()

Re: С++, запрет на использование функции родителя

Уф ).

Ну представь себе класс "ИсследованныеОбъекты", в котором есть массив из объектов типа "ЭлементарнаяЧастица". У объекта "ЭлементарнаяЧастица" есть много свойств: масса, заряд и т.д. И всех всё замечательно устраивает, все этим пользуются, и вдруг у частицы открывают новое свойство. Создаётся класс-потомок "НоваяЭлементарнаяЧастица". Соответственно надо вносить изменения в "ИсследованныеОбъекты": переопределить массив на тип "НоваяЭлементарнаяЧастица", добавить несколько новых функций. И переопределить все те, для которых критично что массив был именно типа "ЭлементарныеЧастица": например, выделяющие память.

octy ★★ ()

С++, запрет на использование функции родителя

class IObjects {};

template<typename T>
class Objects : public IObjects
{
private:
    std::vector<T> particles_;
};

в специализации шаблона описываются функции, чья реализация зависит от интерфейса типа T (частиц); выделение памяти к ним не относится

jtootf ★★★★★ ()

С++, запрет на использование функции родителя

че-то ты невнятное рассказал

но можно определить чистую виртуальную функцию с телом, чтобы потом ее вызывать в потомках

The pure virtual function declaration provides only the prototype of the method. Although an implementation of the pure virtual function is typically not provided in an abstract class, it may be included, although the definition may not be included at the point of declaration [1]. Every non-abstract child class is still required to override the method, but the implementation provided by the abstract class may be called in this way:

class Abstract {
public:
   virtual void pure_virtual() = 0;
};


void Abstract::pure_virtual() {
  // do something
}
 
class Child : public Abstract {
  virtual void pure_virtual(); // no longer abstract, this class may be
                               // instantiated.
};
 
void Child::pure_virtual() {
  Abstract::pure_virtual(); // the implementation in the abstract class 
                            // is executed
}

www_linux_org_ru ★★★★★ ()

С++, запрет на использование функции родителя

> в специализации шаблона описываются функции, чья реализация зависит от интерфейса типа T (частиц); выделение памяти к ним не относится

вполне возможно топикстартеру нужны именно шаблоны, но я на всякий случай рассказал, как дать чистой виртуальной функции тело

www_linux_org_ru ★★★★★ ()

С++, запрет на использование функции родителя

> c->h(); // а это вызывать ошибку компилляции

ммм... скорее всего тебя не дадут уже Child *c = new Child();

да и вообще, что за странное выделение объекта в куче?

www_linux_org_ru ★★★★★ ()

С++, запрет на использование функции родителя

> А что не так с созданием объекта в куче?

м.б. в данном примере оно смотрится странно, а если бы было return c; или Parent* c = new Child(); то смотрелось бы более понятно, впрочем, это все фигня.

www_linux_org_ru ★★★★★ ()

С++, запрет на использование функции родителя

>Т.е. я хочу убедиться, что некая функция в классе-потомке обязательно была переопределена

Внутри этой функции проверяй свой фактический тип через RTTI. Если не совпадает - падай через assert. А статическая фагготрия породит больше проблем в организации проекта чем решит.

Absurd ★★★ ()

С++, запрет на использование функции родителя

Очень плохо продуман дизайн имхо. И RTTI тут - костыль. То, что вполне логично проверять в compile time переносить на RTTI из-за плохого дизайна - вот это фагготрия.

ratatosk ()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.