重载超类的函数

Posted

技术标签:

【中文标题】重载超类的函数【英文标题】:Overloading a super class's function 【发布时间】:2011-06-03 13:54:31 【问题描述】:

C++ 标准中有什么东西阻止我吗?

从这对类开始:

class A             // super class
    int x;

public:
    void foo (int y) x = y;  // original definition
;

class B : public A  // derived class
    int x2;

public:
    void foo (int y, int z) x2 = y + z;  // overloaded
;

我可以轻松拨打B::foo()

    B b;
    b.foo (1, 2);  // [1]

但如果我尝试打电话给A::foo() ...

    B b;
    b.foo (12);    // [2]

...我得到一个编译器错误:

test.cpp: In function 'void bar()':
test.cpp:18: error: no matching function for call to 'B::foo(int)'
test.cpp:12: note: candidates are: void B::foo(int, int)

为了确保没有遗漏任何内容,我更改了B 的函数名称,以免过载:

class B : public A 
    int x2;

public:
    void stuff (int y, int z) x2 = y + z;  // unique name
;

现在我可以使用第二个示例调用A::foo()

这是标准吗?我正在使用 g++。

【问题讨论】:

【参考方案1】:

您需要在类B的定义中使用 using 声明:

class B : public A 
public:
    using A::foo;          // allow A::foo to be found
    void foo(int, int);
    // etc.
;

如果没有 using 声明,编译器会在名称查找期间找到 B::foo,并且实际上不会在基类中搜索具有相同名称的其他实体,因此找不到 A::foo

【讨论】:

“取消隐藏”原来的成员函数。 +1 -- 请注意,Scott Meyers 的有效 C++ 第 33 条:避免隐藏继承的名称(更详细地介绍了这一点)。【参考方案2】:

您并没有覆盖A::foo(int) 的实现,而是将A::foo 别名化并将其签名更改为(int,int) 而不是(int)。正如 James McNellis 提到的,using A::foo; 声明使 A 中的函数可用。

【讨论】:

OP没有说“压倒一切”,他说重载,重载就是他正在做的事情。覆盖适用于虚函数。 他所做的是试图做的是超载。相反,他所做的是类似于覆盖的事情,但还有一个额外的好处是对原始方法进行别名处理。正如 James McNellis 所指出的,using 语句解决了这个问题,允许重载。

以上是关于重载超类的函数的主要内容,如果未能解决你的问题,请参考以下文章

构造函数重载 - Java 中的最佳实践 [关闭]

将工作委派给超类的构造函数[重复]

为啥在声明子类的对象时会调用超类的构造函数? (爪哇)

Swift - 在超类的覆盖函数中返回子类类型

如何在 C++ 子类的构造函数中初始化超类的 const 成员变量?

c ++返回子类,其中函数返回指向超类的指针