биометрия — реализация интерфейса C ++ и инсталяция подклассов объектов

Обновить
Фактический контекст заключается в том, что мне нужно создать пакет для отправки в NIST, пытаясь протестировать алгоритм распознавания лиц, над которым я работаю. API для использования можно найти на NIST API и проект для мерзости в мерзавец проект

Некоторый код для составления резюме сценария:

хиджры — интерфейс A, составленный из чисто виртуальных методов и одного статического метода (frvt11.h в проекте NIST)

class A {
public:
virtual ~A() {}
virtual void pure_virtual_method_a() = 0;
virtual void pure_virtual_method_b() = 0;
static int static_method();
}

b.h — заголовочный файл для b.cpp, где реализованы методы интерфейса A

#include "a.h"
class B : A {
public:
void pure_virtual_method_a();
void pure_virtual_method_b();
static int static_method();
}

b.cpp — Реализация методов интерфейса.

#include "b.h"
void pure_virtual_method_a() {/*implementation*/};
void pure_virtual_method_b() {/*implementation*/};
int static_method() {/*implementation*/};

c.cpp — Файл только с основным методом, и я хочу создать экземпляр объекта B для использования его методов.

#include "b.h"
int main(){
B obj;
obj.pure_virtual_method_a();
return 0;
}

Вопрос 1: Чтобы создать экземпляр объекта B в c.cpp, нужно ли мне создавать заголовочный файл b.h, как описано выше? Это кажется излишним! Похоже, интерфейс A так ненужен 🙁

Вопрос 2: Представленный код является правильным способом реализации интерфейса A и использования объекта B?

Вопрос 3: мне нужно объявить конструктор B в b.h и реализовать его в b.cpp?

2

Решение

Вопрос 1

Вы пропускаете точку с запятой после закрывающей фигурной скобки, и лучше указать, что чистые виртуальные методы, которые вы реализуете в B помечены как override, Это позволяет компилятору выдавать предупреждения в случае, если вы забудете изменить любое из переопределенных объявлений методов, как только соответствующие чистые виртуальные методы в A изменилось бы. Таким образом, вы получите:

#include "a.h"
struct B : public A {
void pure_virtual_method_a() override;
void pure_virtual_method_b() override;
static int static_method();
};

Из этого также ясно, что для того, чтобы компилятор мог объявить B как тип, A должно быть объявлено также. Например, как компилятор проверит override ключевое слово, если оно еще не имеет декларации A, Если у вас не будет переопределенных виртуальных методов, A все еще должен быть известен, так как компилятор должен быть в состоянии определить размер B,

Кроме того, как уже упоминалось в комментариях, B как struct позволяет бросить public ключевое слово, так как видимость по умолчанию struct является публичным в отличие от private видимость по умолчанию для класса. Это единственное различие между классами и структурами в C ++. Таким образом, для интерфейсов использование структур более естественно.

вопрос 2

Не полностью. b.cpp должен выглядеть следующим образом:

#include "b.h"
void B::pure_virtual_method_a() {/*implementation*/};
void B::pure_virtual_method_b() {/*implementation*/};
int B::static_method() {/*implementation*/};

В противном случае вы объявляете и определяете три метода в глобальном пространстве имен, и компоновщик будет жаловаться на неопределенные ссылки на три метода B объявлено в b.h.

Более того, B должен знать, как извлечь из Aлибо публично, защищенно, либо приватно.

Кроме того, было бы неплохо добавить в заголовочные файлы элементы защиты включения, чтобы компилятор не видел дважды одно и то же объявление типа при компиляции объектного файла, например a.o или же b.o:

#ifndef B_H
#define B_H

#include "a.h"
struct B : public A {
...
};

#endif

В заключение, static_method() нужна реализация для A также статические методы не могут быть виртуальными.

Вопрос 3

Вам не нужно реализовывать конструктор для B обязательно. Если вы не определите его, компилятор сгенерирует конструктор по умолчанию для B, Однако, если вы определяете конструктор не по умолчанию для A, вам нужно будет определить один для B в случае, если вы хотите создать экземпляры типа B, Конструктор может быть встроен в заголовочный файл или может быть определен в b.cpp.

1

Другие решения

Вопрос 1.

Вы можете использовать Factory Pattern, тогда вы можете добавить b.h только в файлах Factoru? и вернуть указатели или умный указатель на класс А. Например, это может быть заводская функция:

std::unique_ptr<A> getObject(/*params*/)
{
return std::make_unique<B>(/*params*/)
}

А затем в файле c.cpp:

auto obj = getObject(/*params*/);
obj->pure_virtual_method_a();

Затем вы можете создать еще одну реализацию A интерфейс и вернуть их с завода.

Вопрос 2.

должно быть class B : public A

а также

void B::pure_virtual_method_a() {/*implementation*/};
void B::pure_virtual_method_b() {/*implementation*/};
int B::static_method() {/*implementation*/};

Вопрос 3

Если вам нужен конструктор в class A или конструктор именно для class B, вам нужно определить и реализовать конструктор класса B.

0

По вопросам рекламы [email protected]