在继承中实现虚函数
Implementing virtual functions in inheritance
我有一个用 c++ 处理 类 的练习,我在其中创建了一个文件系统,就像这样 (File.h
)
class File {
public:
virtual string getName();
virtual void print() const=0;
virtual bool operator==(const File& file) const=0;
}
然后,我在 File.cpp
中实现 getName
并创建 TextFile.h
class TextFile : public File {
public:
void print() const;
void operator==(const TextFile& textFile) const;
private:
string text_;
在 TextFile.cpp
中实施
void TextFile :: print() const {
cout << text_ << endl;
}
bool TextFile :: operator==(const TextFile& textFile) const {
return true; //just for compiling
}
编译时我们得到:
$ g++ -Wall -g File.cpp TextFile.cpp -o RunMe
TextFile.cpp: In function ‘int main()’:
TextFile.cpp:8:11: error: cannot declare variable ‘Ilan’ to be of abstract type ‘TextFile’
TextFile Ilan("Ilan", NULL, "Blah \n NewLine");
^
In file included from TextFile.cpp:1:0:
TextFile.h:8:7: note: because the following virtual functions are pure within ‘TextFile’:
class TextFile: public File
^
In file included from TextFile.h:4:0,
from TextFile.cpp:1:
File.h:57:18: note: virtual bool File::operator==(const File&) const
virtual bool operator==(const File& file) const = 0;
我可能不知道如何很好地使用继承和运算符函数(看到 print
函数很好用),但是在浏览我的课程时我找不到问题 material.
行
bool operator==(const &TextFile textFile) const {
不正确 - 应该是
bool TextFile::operator==(const TextFile& textFile) const {
因为需要定义。
超载与覆盖...
在File
中声明虚函数
bool operator==(const File & file) const
一样纯粹。 (= 0
)。所以 File
是一个抽象的 class,它的子 class 也没有被覆盖。
在 TextFile
中,您 重载 它具有同名的函数 (operator==
)
bool operator==(const TextFile & textFile) const
但您不会覆盖它,因为参数的类型不同。因此 TextFile
是一个抽象 class 因为
bool TextFile::operator==(const File & file) const
仍未定义。
编辑:如果您使用 C++11 关键字 "override",编译器可以检测到此类问题。在 TextFile.h
中:
class TextFile : public File
{
...
void print() const override;
bool operator== (.....) const override;
...
}
一条消息将告知这些函数是否实际上没有在它们应该执行的操作时覆盖。
编译器告诉你它不能将 Ilan 声明为 "Textfile" 类型,因为 "virtual function is pure",然后给你纯虚函数的名称。
在 C++ 中,纯虚函数是已声明为虚函数且未定义实现的函数。如果 class 具有 任何纯虚拟 函数,则它是一个虚拟 class,并且您无法创建该 class 的实例。这对于创建抽象接口很有用,这是您对父级所做的 class.
在您的例子中,您已在 TextFile 声明中指定 == 运算符为 class 运算符,但您已在全局命名空间中定义了 == 运算符。要更正此问题,您可以 声明 全局命名空间中的 == 运算符,或将其定义为 TextFile 的一部分(如 Ed Heal 所建议的),但由于某些原因,您应该更喜欢前者此处讨论:Operator overloading : member function vs. non-member function?
File.h
class File {
public:
virtual string getName() const=0;
virtual void print() const=0;
};
文字File.h
class TextFile : public File {
public:
string getName() const;
void print() const;
bool operator==(const TextFile& textFile) const;
private:
string text_;
};
TextFile.cpp
string TextFile ::getName() const{
return text_;
}
void TextFile :: print() const {
cout << text_ << endl;
}
bool TextFile :: operator==(const TextFile& textFile) const {
return text_==textFile.text_;
}
我有一个用 c++ 处理 类 的练习,我在其中创建了一个文件系统,就像这样 (File.h
)
class File {
public:
virtual string getName();
virtual void print() const=0;
virtual bool operator==(const File& file) const=0;
}
然后,我在 File.cpp
中实现 getName
并创建 TextFile.h
class TextFile : public File {
public:
void print() const;
void operator==(const TextFile& textFile) const;
private:
string text_;
在 TextFile.cpp
void TextFile :: print() const {
cout << text_ << endl;
}
bool TextFile :: operator==(const TextFile& textFile) const {
return true; //just for compiling
}
编译时我们得到:
$ g++ -Wall -g File.cpp TextFile.cpp -o RunMe
TextFile.cpp: In function ‘int main()’:
TextFile.cpp:8:11: error: cannot declare variable ‘Ilan’ to be of abstract type ‘TextFile’
TextFile Ilan("Ilan", NULL, "Blah \n NewLine");
^
In file included from TextFile.cpp:1:0:
TextFile.h:8:7: note: because the following virtual functions are pure within ‘TextFile’:
class TextFile: public File
^
In file included from TextFile.h:4:0,
from TextFile.cpp:1:
File.h:57:18: note: virtual bool File::operator==(const File&) const
virtual bool operator==(const File& file) const = 0;
我可能不知道如何很好地使用继承和运算符函数(看到 print
函数很好用),但是在浏览我的课程时我找不到问题 material.
行
bool operator==(const &TextFile textFile) const {
不正确 - 应该是
bool TextFile::operator==(const TextFile& textFile) const {
因为需要定义。
超载与覆盖...
在File
中声明虚函数
bool operator==(const File & file) const
一样纯粹。 (= 0
)。所以 File
是一个抽象的 class,它的子 class 也没有被覆盖。
在 TextFile
中,您 重载 它具有同名的函数 (operator==
)
bool operator==(const TextFile & textFile) const
但您不会覆盖它,因为参数的类型不同。因此 TextFile
是一个抽象 class 因为
bool TextFile::operator==(const File & file) const
仍未定义。
编辑:如果您使用 C++11 关键字 "override",编译器可以检测到此类问题。在 TextFile.h
中:
class TextFile : public File
{
...
void print() const override;
bool operator== (.....) const override;
...
}
一条消息将告知这些函数是否实际上没有在它们应该执行的操作时覆盖。
编译器告诉你它不能将 Ilan 声明为 "Textfile" 类型,因为 "virtual function is pure",然后给你纯虚函数的名称。
在 C++ 中,纯虚函数是已声明为虚函数且未定义实现的函数。如果 class 具有 任何纯虚拟 函数,则它是一个虚拟 class,并且您无法创建该 class 的实例。这对于创建抽象接口很有用,这是您对父级所做的 class.
在您的例子中,您已在 TextFile 声明中指定 == 运算符为 class 运算符,但您已在全局命名空间中定义了 == 运算符。要更正此问题,您可以 声明 全局命名空间中的 == 运算符,或将其定义为 TextFile 的一部分(如 Ed Heal 所建议的),但由于某些原因,您应该更喜欢前者此处讨论:Operator overloading : member function vs. non-member function?
File.h
class File {
public:
virtual string getName() const=0;
virtual void print() const=0;
};
文字File.h
class TextFile : public File {
public:
string getName() const;
void print() const;
bool operator==(const TextFile& textFile) const;
private:
string text_;
};
TextFile.cpp
string TextFile ::getName() const{
return text_;
}
void TextFile :: print() const {
cout << text_ << endl;
}
bool TextFile :: operator==(const TextFile& textFile) const {
return text_==textFile.text_;
}