C ++接口实现和子类对象声明

时间:2018-07-03 18:55:00

标签: c++ inheritance subclassing

更新 实际情况是我需要创建一个要提交给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中实现它?

2 个答案:

答案 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.ob.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类构造函数。