Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/163.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
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 - Fatal编程技术网

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++;继承不继承外祖父文件 最近我尝试解决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

这是我的“祖父”标题,名为“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.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;