Как правильно использовать интерфейсы и абстракцию данных вместе в C++?

Я довольно уверен в C и Java и только начал использовать C++, все еще привыкая к основам о лучших практиках, включая абстракцию данных (что, насколько я понимаю, означает правильное использование заголовков).

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

Мой заголовок выглядит так:

#include <iostream>

using namespace std;

class Problem {
public:
    /*
    * Read data from file.
    */
    virtual bool read(string filename) = 0;

    /*
     * Solve problem.
     */
    virtual void solve() = 0;

    /*
     * Write solution to file.
     */
    virtual bool write(string filename) = 0;
};

class Brothers : public Problem {};

Я пытаюсь реализовать первую функцию в моем Brothers.cpp Исходный файл, как это:

bool Brothers::read(string filename) override {...}

Который, за исключением Brothers:: Часть, как я обычно реализую эту функцию, если бы у меня были только исходные файлы.

Я получаю ошибки Function 'read' was not declared in class 'Brothers' а также Function doesn't override any base member functionsи я хотел бы понять, почему этот подход не работает и что я должен делать вместо этого.

1 ответ

Решение

Даже если вы переопределяете объявление базового класса, в отличие от java, вам все равно нужно объявить функцию в заголовочном файле производного класса. Компилятор смотрит только в классе, связанном с этой функцией, поэтому, когда вы говорите, что есть функция read в Brother и он не может видеть, что есть одно явно, вы получаете ошибку.
Другое дело, что когда вы используете интерфейсы или другие абстрактные классы, все, что объявлено как чисто виртуальное, должно быть определено до того, как появится класс, который не является чисто виртуальным, поэтому в этом примере:

class A
{
    virtual void foo() = 0;
}

class B : public A
{
    virtual int bar()
    {
        return 0;
    }
}

class C : public B
{
    virtual void foo()
    {
        // Do something
    }
}

Учебный класс A является абстрактным, потому что он имеет чисто виртуальную функцию, но это так B потому что он до сих пор не имеет определения foo(), Пока нет определения для него, не может быть неабстрактных классов.

Другие вопросы по тегам