我有一个基类,它将方法定义为虚拟,这些方法内部没有任何内容,只有声明。我有一个派生自基类的类,并没有实现所有方法,这里出现问题。如果我们调用一个未在派生类上实现但在基础上实现的方法,则会崩溃。
示例(崩溃):
#include <iostream>
class Foo
{
public:
virtual std::string ref() {}
};
class Bar : public Foo {};
int main(int argc, char ** argv)
{
auto foo = new Bar;
auto bar = foo->ref();
return 0;
}
问:在这种情况下,最佳解决方案是什么。
1) - 返回默认(空)值。
virtual std::string ref()
{
return "";
}
2) - 抛出一个不能直接从基类调用方法的异常。
virtual std::string ref()
{
throw std::runtime_error(":(");
}
谢谢。
答案 0 :(得分:4)
这就是纯虚拟用途:
virtual std::string ref() = 0;
现在,编译器不允许您实例化未定义该函数的派生类型的实例。
答案 1 :(得分:2)
如果我们调用的方法没有在派生类上实现,但是 在基地,它崩溃。
这并不严格适用于您的示例代码:
virtual std::string ref() {}
有实施;你得到了一个崩溃因为实施没有返回任何东西。这可能会发生在这里,例如:
#include <string>
std::string f() {}
int main()
{
std::string x = f();
x = "";
}
(我说&#34;很可能&#34;因为它的未定义行为,所以不能保证崩溃。)
至于你的问题:
如果你需要调用概念上不存在的函数,那么你就会遇到设计问题;很可能你的基类试图同时履行太多的职责。
否则,使用抽象类。您可以通过声明至少一个函数 pure virtual :
来使类抽象化class Foo
{
public:
virtual std::string ref() = 0; // pure virtual function
};
请注意另外三件事:
最后的例子:
class Foo
{
public:
virtual ~Foo() {}
std::string ref() const { return refImpl(); }
private:
virtual std::string refImpl() const = 0;
};