说我们有这个:
class A
{
public:
virtual void foo() = 0;
};
class B: public A
{
public:
virtual void foo() = 0;
};
编译器不会抛出任何错误,我猜它是因为B也是一个抽象类,因此它不必从A实现foo
。
但这样的构造意味着什么?
1)B中的foo
是否隐藏foo
来自A?
2)继承自B并且不是抽象类的第一个类,它必须提供两个实现,如:
class C: public B
{
public:
virtual void A::foo() {};
virtual void B::foo() {};
};
编译器只会抱怨B::foo()
的实现缺失,但不会抱怨缺少A::foo()
。
总而言之:这是一种隐藏纯虚方法的方法吗?
答案 0 :(得分:9)
当你第一次宣布:
class A
{
public:
virtual void foo() = 0;
};
您声明方法foo
是公共的,虚拟的和纯粹的。当一个类至少包含一个纯方法时,它被称为 abstract 。这是什么意思?这意味着该类无法实例化,因为它需要纯方法实现。
你显然可以从一个抽象类继承(我会说你被迫这样做,否则你需要一个你没有使用的抽象类,除了提供一个继承的接口?)和你也可以从一个抽象类继承而不是实现父类的部分或全部纯方法;在这种情况下,子类也是抽象的,就像你的B类一样:
class B: public A
{
public:
virtual void foo() = 0;
};
在B中,您可以轻松省略virtual void foo() = 0;
声明,因为该定义已从基类继承。在这种情况下,类B是一个抽象类,因此无法实例化,就像A。
更直接地回答您的问题:
来自B的
foo
是否隐藏foo
来自A?
不,它没有。它们都声明了一个纯方法(事实上它是相同的方法),因此没有什么可以真正隐藏。
第一个继承自B并且不是抽象类的类,是否必须提供两个类似提供的实现?
不,当然不是。如上所述,它们是相同的方法,因此如果C类必须为foo
提供实现,它应该只实现foo
:
class C: public B
{
public:
virtual void foo() {};
};
答案 1 :(得分:7)
0)编译器不会抛出错误...
当您尝试从A
或B
实例化一个对象时,它会引发错误。不是在你继承和宣布它们的时候。
1)B的foo是否隐藏了A?
没有。它超越A::foo
而不是隐藏它。
2)继承自B并且不是抽象类的第一个类, 是否必须提供两种实现方式......
没有。只需覆盖foo
并为其创建一个实现。
class C : public B
{
public:
virtual void foo()
{
std::cout << "ABCD" << std::endl;
}
};
int main()
{
C c;
A *a = &c;
a->foo(); // Prints ABCD string and proofs B::foo doesn't hide A::foo
}
答案 2 :(得分:1)
我用gcc 4.5.3编译了你的代码,它给出了以下错误信息:
error: cannot define member function ‘A::foo’ within ‘C’
error: cannot define member function 'B::foo' within 'C'
在您的示例中,类A
和B
都是抽象类,因为foo是纯虚拟的。它们只定义B的派生类应该实现foo
的行为,因为没有默认行为要使用(如果派生类不再是抽象的)。
Question 1:Does foo from B hide foo from A?
由于foo
和B
中的A
具有完全相同的名称,因此相同的签名和foo在基类中是虚拟的,因此它不会隐藏,它会覆盖。仅供参考:如果签名相同并且在基类中声明为虚拟,则派生类的函数overrides
是基类函数。如果你打电话
通过指针或对基类的引用,在函数中
派生类被调用。它“覆盖”基类中的那个。
Hiding
只有在通过a调用非虚函数时才会发挥作用
指针或引用或直接与派生类的对象。一个
派生类'函数隐藏所有具有相同名称的基类函数。
Question 2: The first class which inherits from B and is not an abstract class, does it have to provide two implementations
没有。您可以执行以下操作:
class C: public B
{
public:
virtual void foo()
{
cout << "foo defined in c" <<endl;
}
};