纯虚函数的过载问题

7
我通常使用纯虚函数来实现那些代码需要的方法。因此,我创建接口,然后其他用户实现它们的派生类。派生类只将这些虚函数作为公共函数,而一些额外的方法应该被实现为私有函数,因为我的代码不会调用它们。 我不知道这是否可以视为良好的面向对象编程实践(是否有设计模式?)。 无论如何,我的问题是: 用户能否重载纯虚函数?
即:
class Base
{
public:
 Base();
 virtual ~Base();
 virtual void foo(int,double)=0;
};

class Derived:
public Base
{
 private:
  // methods
 public:
 Derived();
 virtual ~Derived();
 virtual void foo(int, double, double); //this doesn't work
 };

一个解决方案可以是:
 virtual void foo(int,double,double=0)=0;

基类中提供了一些功能,但是非常有限。你认为呢?


1
函数重载代表着不同的API。抽象基类则代表着一致的API。因此,这是没有意义的。 - Oliver Charlesworth
你的例子是否漏了class Derived : Base - nonsensickle
@nonsensical:好的,我刚刚编辑了。谢谢。 - Ale
6个回答

10

这两个函数是不同的,后一个函数没有覆盖第一个函数。

virtual void foo(int,double)=0;
virtual void foo(int, double, double);

第二个是针对派生类的新虚函数。

如果在末尾加上override,编译器会抱怨您没有覆盖任何内容。这是C++11的检查。

virtual void foo(int, double, double) override;

用户可以通过在函数末尾加上override来覆盖纯虚拟函数并进行确认。在您的情况下,只能使用派生指针或类型访问第二个函数。(虽然除非正确重写和实现纯虚拟函数,否则无法实例化它,直到那时它才是抽象类)。因此,如果不打算进一步从继承自Derived的类中覆盖,则将其设置为虚拟的是一种负担,因为它无论如何都不会覆盖基本方法。


当我正在写有关“override”的内容时,这个答案就出现了。所以至少在这里提供链接:http://msdn.microsoft.com/en-us/library/vstudio/jj678987.aspx - Kupto
@Kupto:为什么在第一个例子中,funcC(double = 0.0)的覆盖(override)有效,而在第二个代码中不起作用? - Ale
@Ale,我刚试了一下,如果考虑到注释的话,第一个示例中的“override”关键字似乎是多余的。 - Kupto

4
你无法这样做。
假设你有一个指向派生类对象的基类指针。通过基类指针,你只能访问基类接口(除非你将其转换为派生类指针,但这不是你需要的)。

1
是的,这确实是一个问题。所以唯一的解决方案就是创建一个抽象类而不是接口。对吧? - Ale
@Ale - 我不明白你的意思。在C++中,“接口”和“抽象类”有什么区别? - Kiril Kirov
一个派生类可以拥有比抽象类更多的函数。相反,接口限制了方法的数量(在我看来)。 - Ale

3

重载函数仅仅是和另一个同名,但接收不同参数集合的函数,即它是一个不同的函数。它与一个或多个重载函数是否虚无关。

在您提供的示例中,我认为用户可以重载纯虚函数,但仅在覆盖它后才能这样做。而且你不能直接从基类访问该函数 —— 你需要将基类指针转换为派生类指针。


0

在基类中重载foo难道不是最简单的解决方案吗?

class Base
{
public:
 Base();
 virtual ~Base();
 virtual void foo(int,double)=0;
 virtual void foo(int,double,double)=0;
};

0

正如其他人指出的那样,它根本行不通。

更加谨慎地说,以下是发生的情况

 Derived d;
 d.foo(5, 10.0); // Works as expected

 Base &b = d; // b is polymorphic
 b.foo(3,10,4); // foo(int, double, double) is not in class Base, hence compile-time resolution fails!

0

由于函数签名不同,因此它不会覆盖。根据多态规则,要重写函数,函数签名和类型应该相同。

在这种情况下,这些函数是不同的。 virtual void foo(int,double)=0; virtual void foo(int, double, double);


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接