C ++ Сделать функцию недоступной в дочернем классе - PullRequest
0 голосов
/ 09 октября 2018

У меня сложный родительский класс, который наследуется.Сейчас мне нужно просто переопределить несколько его функций и я хотел бы как-то предотвратить возможность вызова некоторых не переопределенных функций родительского класса в дочернем объекте (эти функции из родительского класса не будут работать должным образом).Я бы определил их позже, если необходимо, просто хочу прояснить, что на данный момент они не могут использоваться, , но все же наследуют некоторые функции, чтобы сделать возможным полиморфизм .Можно ли этого добиться?Или мне нужно изменить дизайн?

Вот небольшой пример:

class ParentClass
{
public:
    virtual void write() { ... }
    virtual void read() { ... }
    virtual void calculate() { ... }
};

class ChildClass : public ParentClass
{
public:
    void calculate() override { ... }
};

Я бы хотел запретить возможность вызова функций read или write из ChildClass объект, потому что эти функции сложно определить, и они мне сейчас не нужны.Но в то же время я хотел бы запретить кому-либо использовать наследуемые от родителя функции в ChildClass.Что важно, Parent class определено в сторонней библиотеке, и я не могу изменить родительский класс.

Моя (неуклюжая) идея состояла в том, чтобы переопределить эти функции и добавить их, чтобы было очевидно, что онинедоступен, но это так далеко от правильного дизайна ... Какое может быть правильное решение?

Ответы [ 2 ]

0 голосов
/ 09 октября 2018

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

Вот пример:

#include <stdio.h>

class ParentClass
{
public:
    virtual void write() { printf("write"); }
    virtual void read() { printf("read"); }
    virtual void calculate() { printf("calculate"); }
    virtual void other() { printf("other"); }

};

class ChildClass : private ParentClass
{
public:
    void calculate() override { printf("new calculate"); }
    using ParentClass::other;
};

int main() {
    ChildClass c;
    c.calculate();
    c.other();
}

В проводнике компилятора Godbolt я получаю эту сгенерированную сборку (как и ожидалось)

.LC0:
  .string "new calculate"
.LC1:
  .string "other"
main:
  sub rsp, 8
  mov edi, OFFSET FLAT:.LC0
  xor eax, eax
  call printf
  mov edi, OFFSET FLAT:.LC1
  xor eax, eax
  call printf
  xor eax, eax
  add rsp, 8
  ret

Синтаксис using ParentClass::other (для пересылки функции из базового класса без изменений) только C ++ 11, вы не пометили функцию c ++ 11, поэтому я не знаю, можете ли вы использовать это :), но это удобно

0 голосов
/ 09 октября 2018

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

Я думаю, вы можете объявить их как deleted вдочерний класс, оставляя их виртуальными в базовом классе.Это должно вызвать ошибку времени компиляции, когда вы пытаетесь использовать ее для объекта из дочернего класса.То есть в дочернем классе:

void write = deleted;
void read = deleted;

К сожалению, я не уверен на 100%, что это будет работать с виртуальной функцией.Если нет, вы также можете попытаться удалить ключевое слово virtual из этих функций в родительском классе и использовать обычную перегрузку в дочернем классе с удаленными функциями, как описано выше, или даже просто объявить их, не определяя их (я предпочитаю удаленные функции такими, какие они есть).более явно).Опять же, это должно вызвать ошибку времени компиляции.Вы, конечно, потеряете преимущество полиморфизма.

Дайте мне знать, если эти решения работают.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...