更新 实际情况是我需要创建一个要提交给NIST的程序包,以尝试测试我正在研究的面部识别算法。可以在NIST API找到要使用的API,在git project上找到git项目
一些代码可以对场景进行总结:
a.h -接口A
,由纯虚拟方法和一种静态方法组成(NIST项目为frvt11.h)
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 -接口A
的方法的实现。
#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
中实现它?
答案 0 :(得分:1)
问题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.h 中声明的B
的三个方法的引用。
此外,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 :(得分:0)
问题1。
您可以使用Factory Pattern,然后您只能在Factoru文件中添加b.h吗?并返回指向A类的指针或智能指针。例如,它可以是工厂功能,例如:
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类构造函数。