它必须是我的代码中特定的内容,我无法发布。但也许有人可以提出可能的原因。
基本上我有:
class CParent
{
public:
void doIt(int x);
};
class CChild : public CParent
{
public:
void doIt(int x,int y,int z);
};
CChild *pChild = ...
pChild->doIt(123); //FAILS compiler, no method found
CParent *pParent = pChild;
pParent->doIt(123); //works fine
到底是怎么回事?
编辑:人们在谈论阴影/隐藏。但是两个版本的doIt具有不同数量的参数。当然不能混淆编译器,子类中的重载哪些不可能与父类版本混淆?可以吗?我得到的编译器错误是: 错误C2660:'CChild :: doIt':函数不带1个参数
答案 0 :(得分:29)
你已经隐藏了一个方法。例如:
struct base
{
void method(int);
void method(float);
};
struct derived : base
{
void method(int);
// base::method(int) is not visible.
// base::method(float) is not visible.
};
您可以使用using
指令解决此问题:
class derived : public base
{
using base::method; // bring all of them in.
void method(int);
// base::method(int) is not visible.
// base::method(float) is visible.
};
由于您似乎坚持参数数量,我将解决这个问题。 这不会改变任何事情。观察:
struct base
{
void method(int){}
};
struct derived : base
{
void method(int,int){}
// method(int) is not visible.
};
struct derived_fixed : base
{
using base::method;
void method(int,int){}
};
int main(void)
{
{
derived d;
d.method(1, 2); // will compile
d.method(3); // will NOT compile
}
{
derived_fixed d;
d.method(1, 2); // will compile
d.method(3); // will compile
}
}
无论参数或返回类型如何,仍然被遮蔽;它只是阴影的名称。 using base::<x>;
会将所有base
的“<x>
”方法置于可见状态。
答案 1 :(得分:2)
你遇到了一个经典问题。您的CChild课程需要using CParent::doIt;
。我会仔细研究重复的问题。
编辑:
以下是我对基本相同问题的回答:Overriding a Base's Overloaded Function in C++
答案 2 :(得分:1)
我以前从未在基类中使用过该方法。我认为在派生类中添加“使用CLASS :: METHOD”将允许您访问重载方法的其他版本。
class CParent
{
public:
void doIt(int x);
};
class CChild : public CParent
{
public:
void doIt(int x,int y,int z);
using CParent::doIt;
};
答案 3 :(得分:0)
问题是CChild
实际上并未从CParent
继承。
因此它没有只占用一个参数的doIt
方法。
答案 4 :(得分:0)
当您覆盖派生类中的函数时,只有派生类中的该函数对该类的用户可见。基类版本变为隐藏。
因此,调用doIt(int x)的pChild指针将失败,因为您使用派生类指针来调用基类函数。调用doIt(int x)的pParent指针将起作用,因为您使用基类指针来调用基类函数。即使你有一个子对象被父指针指向(upcasted),这里的类类型由指针的声明决定。
为了能够使用派生类指针调用该基类函数,您可以:
在函数调用中限定基类名称,如下所示:
pChild->CParent::doIt(123);
使用using指令将基类中的函数名称引入派生类,如前面的帖子所示。
答案 5 :(得分:0)
我理解这种行为是为了让您灵活地覆盖派生类中基类方法的行为。
让我们假设您在基类中有一个函数foo(int),并且您希望在派生类中更改此函数的行为。现在,如果派生类方法没有隐藏基类方法(它具有与基类方法相同的原型),则会在重载决策中引入歧义。
答案 6 :(得分:-2)
您的子类中的方法具有与您尝试传递给它的参数数量不同的参数。它可能与此有关吗?