2014-05-23 71 views
2

我有一个由source.c:这些课程为什么不完整?

#include "image.h" 

#ifndef SOURCE_H 
#define SOURCE_H 

class Source 
{ 
    private: 
     Image* img; 
    public: 
     virtual void Execute()=0; 
     Image* GetOutput(); 
}; 
#endif 

Image* Source::GetOutput() 
{ 
    return this->img; 
} 

和sink.C.

#include "image.h" 


#ifndef SINK_H 
#define SINK_H 
class Sink 
{ 
    private: 
     Image* img1; 
     Image* img2; 

    public: 
     void SetInput(Image* input1); 
     void SetInput2(Image* input2); 
}; 
#endif 

void Sink::SetInput(Image* input1) 
{ 
    this->img1 = input1; 
} 

void Sink::SetInput2(Image* input2) 
{ 
    this->img2 = input2; 
} 

我有我想从源库继承filter.h:

#include "image.h" 
#include <iostream> 
#include <stdlib.h> 

class Source; 
class Sink; 

class Filter : Source, Sink 
{ 
    public: 
     Filter() {std::cout << "Constructing filter." << std::endl;} 
}; 

然而,编译器给我的无效使用不完全类型“类源”和“类的错误水槽'。我也得到这些相同类的前向声明的错误。这些类最初的功能是直接在public中定义的,所以我将它们移出了,但这对此没有帮助。明确地将Source和Sink设置为public也没有帮助。这是怎么回事?

回答

4
#include "sink.h" 
#include "source.h" 

应该排序。

而且这条线: class Filter : Source, Sink

这是私人的继承,这几乎永远是你不想要的东西(你将不能够使用类多态)。

您可能需要改变这

class Filter : public Source, public Sink

+0

+1用于发现私有继承 – mjs

4

向前声明只让编译器知道一个存在,但它并没有告诉这个名字的定义什么。为了继承,必须知道基类的定义。您必须在filter.h中包含标题,以便编译器可以看到父类的定义。

编辑

声明意味着一个名字存在,定义是指什么名字的模样。对于类定义,它意味着类包含什么,它是成员,大小等。当一个类被另一个类继承时,编译器种类放置在派生类中的基类成员。所以它必须知道基类是什么样的。通过在定义基类的头文件中包含头文件,编译器实际上将定义放置在包含的文件中,因此它知道基类。

正如有人指出你私下继承,我建议你阅读is-ahas-a关系和difference between private and public inheritance

+0

你说的定义是什么意思?他们是班级吗? – user3668005

+0

@ user3668005,声明意味着名称存在,定义意味着名称的样子。对于类定义,它意味着类包含什么,它的成员,大小等。 – Rakib

2

这里有两个问题

第一,如其他人所说的,你需要包括Sink和Source的标题。目前,您只有转发声明,它可让您使用指针,但不能派生或实例化。编译器不知道大小,或者提供了什么方法,或者如何构建。

第二个问题,一旦你包含头文件,你会发现,Sink类有一个纯虚函数。这使它成为一个抽象的基类。 你需要从这个(你有)派生并在派生类中实现Execute方法(你没有)

4

这是因为在你filter.h你给一个不完整的申报:

class Source; 
class Sink; 

但没有定义它们。编译器需要知道两者的尺寸,以计算的Filter大小:

class Filter : Source, Sink 
{ 
    public: 
     Filter() {std::cout << "Constructing filter." << std::endl;} 
}; 

的解决方案是包括两个头文件。为此,您可能需要将头文件和源文件中的声明与实现分开。

+0

好的,这是有道理的。原来他们是我的项目中仅有的两个类,我现在没有头文件。我不知道没有他们会影响这一点。 – user3668005