首先,很抱歉标题令人迷惑。我不知道该如何正确表达。
问题不是真正的问题,而是我不知道如何实现的问题。
代码如下:
#include <iostream>
class Parent
{
public:
virtual void foo()
{
std::cout << "Parent's foo" << std::endl;
}
void bar()
{
foo();
}
};
class Child : public Parent
{
public:
void foo()
{
std::cout << "Child's foo" << std::endl;
}
};
int main()
{
Child c;
c.bar();
return 0;
}
上面的代码运行时,它会打印出来Child's foo
。
但是,相同的代码是,子类foo定义为void foo(bool def = true)
的BUT会打印出Parent's foo
。
如果定义不匹配,是否仍然可以调用子版本的foo而不是父版本的foo?
答案 0 :(得分:1)
不幸的是,如果您想添加额外的参数(甚至是默认参数),则可以显式创建一个重载函数,该函数在大多数情况下的行为与调用方相似。
#include <iostream>
class Parent
{
public:
virtual void foo()
{
std::cout << "Parent's foo" << std::endl;
}
void bar()
{
foo();
}
};
class Child : public Parent
{
public:
virtual void foo(bool def) // virtual if another subclass needs to override
{
std::cout << "Child's foo def = " << def << std::endl;
}
virtual void foo()override //override and virtual optional here
{
foo(true);
}
};
int main()
{
Child c;
c.bar();
c.foo();
c.foo(true);
return 0;
}
答案 1 :(得分:0)
这纯粹是在C ++中重写函数时的函数。
在C ++中,函数重写是根据成员函数的“签名”完成的:
this
)this
的限定条件很明显,根据定义,this
参数的类型 不能完全匹配,因为根据定义,该类型必须是指向派生类的指针。
[关于参数的简历限定的注意事项:
调用方看到的声明中的参数必须完全相同,即在删除对象副本上无意义的cv限定符之后:这些是函数体内局部变量的cv限定符,而这仅在函数定义中有意义。
void f(const int i); // takes an int by value; const is meaningless
void f(int i); // redeclaration of the same function
// redeclaration of the same function yet again
void f(const int ci) { // const is meaningful here
ci = 1; // error
}
-尾注]
但是相同的代码,但是带有子类foo的定义
void foo(bool def = true)
会打印出父母的foo。
因为参数列表不匹配:空参数列表仅与空参数列表匹配。
您需要在此处用两个重载函数替换默认参数,而不能转发给另一个:
void foo(bool def); // new function signature
void foo() { // overrides Parent's member
foo(true);
}
参数列表很长,很容易更改类型并创建新的函数签名,而不是覆盖基类虚函数;也很容易弄错大写字母或拼写错误(请考虑英语与美国拼写)。通常,错误的函数名称(或任何其他名称:类型,模板,变量...)会导致编译错误,因为未声明具有较小拼写更改的名称。但是,如果使用成员的原始声明以覆盖基类声明为目的,则没有暗示您尝试这样做,并且编译器不会警告您(它可能会警告隐藏基类声明,但这是不同的)。明确标记要使用virtual
关键字覆盖的声明没有帮助,引入新的虚函数并不是目的。
这是C ++标准的第一个版本正式化之后的悲惨状况。现在不一样了。
如果要确保确实覆盖了基类声明,则可以使用override
关键字:
class Child : public Parent
{
public:
void foo(bool def);
void foo() override {
foo(true);
}
};