我的基本理解是没有纯虚函数的实现,然而,我被告知可能有纯虚函数的实现。
class A {
public:
virtual void f() = 0;
};
void A::f() {
cout<<"Test"<<endl;
}
上面的代码可以吗?
让它成为一个带有实现的纯虚函数的目的是什么?
我的基本理解是没有纯虚函数的实现,然而,我被告知可能有纯虚函数的实现。
class A {
public:
virtual void f() = 0;
};
void A::f() {
cout<<"Test"<<endl;
}
上面的代码可以吗?
让它成为一个带有实现的纯虚函数的目的是什么?
当前回答
如果我问你动物的声音是什么,正确的回答是问哪种动物,这正是纯虚函数或抽象函数的目的,当你不能在基类(animal)中提供函数的实现,但每个动物都有自己的声音。
class Animal
{
public:
virtual void sound() = 0;
}
class Dog : public Animal
{
public:
void sound()
{
std::cout << "Meo Meo";
}
}
其他回答
如果您有应该由派生类执行的代码,但不希望它直接执行——并且希望强制重写它。
您的代码是正确的,尽管总的来说这不是一个经常使用的特性,而且通常只在试图定义纯虚析构函数时才会看到——在这种情况下,您必须提供一个实现。有趣的是,一旦从该类派生出来,就不需要重写析构函数了。
因此,纯虚函数的一个合理用法是将纯虚析构函数指定为“非final”关键字。
下面的代码是惊人的正确:
class Base {
public:
virtual ~Base() = 0;
};
Base::~Base() {}
class Derived : public Base {};
int main() {
// Base b; -- compile error
Derived d;
}
它的优点是它强制派生类型仍然重写方法,但也提供了默认的或添加的实现。
如果我问你动物的声音是什么,正确的回答是问哪种动物,这正是纯虚函数或抽象函数的目的,当你不能在基类(animal)中提供函数的实现,但每个动物都有自己的声音。
class Animal
{
public:
virtual void sound() = 0;
}
class Dog : public Animal
{
public:
void sound()
{
std::cout << "Meo Meo";
}
}
纯虚函数必须在将被直接实例化的派生类型中实现,但是基类型仍然可以定义实现。派生类可以通过使用全作用域名称显式调用基类实现(如果访问权限允许的话)(在示例中调用A::f()—如果A::f()是公共的或受保护的)。喜欢的东西:
class B : public A {
virtual void f() {
// class B doesn't have anything special to do for f()
// so we'll call A's
// note that A's declaration of f() would have to be public
// or protected to avoid a compile time problem
A::f();
}
};
我能想到的用例是,当存在一个或多或少合理的默认行为,但类设计器希望只显式地调用这种默认行为时。也可能是这样,你希望派生类总是执行它们自己的工作,但也能够调用一组公共功能。
请注意,尽管语言允许这样做,但我并没有看到它被普遍使用(而且可以这样做的事实似乎让大多数c++程序员感到惊讶,甚至是有经验的程序员)。
是的,这是正确的。在您的示例中,派生自A的类继承了接口f()和默认实现。但是你强迫派生类实现方法f()(即使它只是调用A提供的默认实现)。
Scott Meyers在Effective c++ (2nd Edition)第36项中讨论了这一点,区分接口的继承和实现的继承。项目编号可能在最新版本中发生了变化。