C++;继承不继承外祖父文件 最近我尝试解决C++继承和多态性,但我有一些问题对我来说毫无意义。 我有两个单独的文件头和一个带有实现的cpp文件。我的代码摘要如下: #ifndef MANDEL_H_ #define MANDEL_H_ class Mandel{ public: virtual void compute("various arguments") = 0; //dummy destructor, I must have one or compile is sad and I dunno why virtual ~Mandel(); private: virtual int compute_point("various arguments") = 0; }; #endif
这是我的“祖父”标题,名为“Mandel.h”。现在转到“父”标题。下一个标题指定了几个特定于Mandel黑白实现的变量,称为“black_white_Mandel.h”: 现在,在一个名为White_Black_Mandel_Imp1.cpp的单独文件中,实现了Black_White_Mandel标头:C++;继承不继承外祖父文件 最近我尝试解决C++继承和多态性,但我有一些问题对我来说毫无意义。 我有两个单独的文件头和一个带有实现的cpp文件。我的代码摘要如下: #ifndef MANDEL_H_ #define MANDEL_H_ class Mandel{ public: virtual void compute("various arguments") = 0; //dummy destructor, I must have one or compile is sad and I dunno why virtual ~Mandel(); private: virtual int compute_point("various arguments") = 0; }; #endif,c++,inheritance,polymorphism,C++,Inheritance,Polymorphism,这是我的“祖父”标题,名为“Mandel.h”。现在转到“父”标题。下一个标题指定了几个特定于Mandel黑白实现的变量,称为“black_white_Mandel.h”: 现在,在一个名为White_Black_Mandel_Imp1.cpp的单独文件中,实现了Black_White_Mandel标头: #include <iostream> #include <unistd.h> #include <stdio.h> #include <stdlib
#include <iostream>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include "Mandel.h"
#include "Black_White_Mandel.h"
using namespace std;
//constructor
Black_White_Mandel::Black_White_Mandel(){
max_iterations = 255;
}
//destructor
Black_White_Mandel::~Black_White_Mandel(){}
int Black_White_Mandel::compute_point("various arguments") {
//code and stuff
return 0;
}
void Black_White_Mandel::compute("various arguments") {
//code and stuff
}
#包括
#包括
#包括
#包括
#包括“Mandel.h”
#包括“黑、白、曼德尔.h”
使用名称空间std;
//建造师
黑人白人曼德尔:黑人白人曼德尔{
最大迭代次数=255次;
}
//析构函数
黑人白人曼德尔::~黑人白人曼德尔(){}
int Black\u White\u Mandel::compute\u point(“各种参数”){
//代码和东西
返回0;
}
void Black\u White\u Mandel::compute(“各种参数”){
//代码和东西
}
因此,Mandel.h有两个函数必须实现,因为它们是虚拟的且“=0”。在White_Black_Mandel_Imp1.cpp中,当我实现这些函数时,编译器会发疯。它说这些函数没有在White_Black_Mandel.h中定义,尽管这是真的,但它们是在Mandel.h中定义的。因此,通过继承,White_Black_Mandel_Imp1.cpp应该知道它有义务从Mandel.h.实现这些功能
我不明白,我的一个朋友说我的White_Black_Mandel.h文件应该是Mandel.h的精确副本,但还有一些额外的东西,但这在我看来真的很愚蠢,毫无意义
我做错了什么?将
compute
和compute\u point
的原型添加到Black\u White\u Mandel
在某些情况下,您从具有纯虚拟函数的基类继承,但没有实现所有这些函数:您的派生类将保持抽象,并且需要由另一个类继承,等等,直到实现所有纯虚拟函数为止
例如
上面唯一可实例化的类是C
和D
白人、黑人、曼德尔和Imp1.cpp应该知道自己有义务
它没有,也不应该。它也可以决定是一个抽象类,在这种情况下,它可以不使用这些函数。尽管您的祖先类中有两个纯虚拟方法,但这并不意味着它们的原型可以在子类中使用 即使在子类中也必须声明原型:
class Black_White_Mandel: public Mandel {
public:
virtual void compute("various arguments")
protected:
int max_iterations; //a specific variable of this Black_White Version
private:
virtual int compute_point("various arguments");
};
virtual
关键字是可选的,但是知道该方法确实是虚拟的很有用。您不必在这个特定的子类中实现它们,您可以避免指定任何东西,但是您仍然有两个必须实现的纯虚拟方法,因此您将无法实例化这个子类的任何对象(您必须在层次结构树中实现它们)
需要虚拟析构函数,因为在其他类似情况下:
Base *derived = new Derived();
delete derived;
编译器无法调用正确的析构函数。您必须在实现类中提供声明的原因是,派生类使用不同的返回类型重写虚拟函数是合法的,只要新的返回类型与原始返回类型一致。例如,基类可以返回BaseReturnedObject&
,但派生类可以选择返回DerivedReturnObject&
。如果派生类中没有声明,编译器就不知道方法的返回类型。它不能假设它与基中的相同,因此编译器需要一个原型
有关使用协变返回类型重写的规则,请参见。假设您的“祖父”类中有4个方法,所有这些方法都是纯虚拟的。现在,您打算在“父亲”类中实现两个,在“孩子”类中实现两个。顺便说一句,这个特殊的术语并不理想,但我坚持使用它,因为你是从它开始的 定义类时(在
类{
和}之间的.h文件中;
告诉编译器哪些函数来自基类(术语中的祖父类)您打算重写。您可以将实现放在标题中,也可以将其放在.cpp文件中。但必须指定要重写的4个函数(如果有)中的哪一个
如果您在类定义中没有提到某个特定的继承函数(正如您所说的在头文件中),那么在编译实现时(在.cpp文件中),编译器会说:“什么?您从来没有告诉我您计划重写此函数!”您的回答似乎是“伙计,这是纯虚拟的,如果我不重写它,我就无法实例化对象!"但你知道吗?编译器对此毫不关心。它不知道你是否试图创建一个可实例化对象,你是否打算进一步继承,甚至不知道函数在基类中是纯虚拟的。它所知道的只是,它正在编译一个实现文件,而它遇到了一个你没有调用的函数我在类定义中提到了它
因此,当您编写一个类something{
..};
类定义时,一定要列出您打算为该类实现的所有函数,无论您是否继承了它们。不要列出您继承的未更改的函数,也不会实现。如果您继承的是接口(所有的函数都是纯虚拟的)那么是的,如果你要实现它们,你必须在类中列出它们。那是因为语言没有为这种情况留出一个特例。这根本不等同于“
class Black_White_Mandel: public Mandel {
public:
virtual void compute("various arguments")
protected:
int max_iterations; //a specific variable of this Black_White Version
private:
virtual int compute_point("various arguments");
};
Base *derived = new Derived();
delete derived;