- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
假设我有这个:
class A
{
public:
virtual int hello(A a);
};
class B : public A
{
public:
int hello(B b){ bla bla };
};
所以,它是一个抽象类。
1) 在 B 类中,我定义了一个方法,它假设重写了 A 类。但参数略有不同。我不确定,这是正确的吗?也许是因为多态性,这没问题,但相当困惑。2) 如果我这样做:A a = new B;,然后 a.hello(lol);如果“lol”不是 B 类型,那么它会给出编译错误?如果它是来自另一个类 C(C 类:public A)的 A 类型,会发生什么?
我对覆盖和虚拟的东西感到困惑。我发现所有示例都使用没有参数的方法。
任何答案、链接或任何值得赞赏的内容。
谢谢
pd:对不起我的英语
最佳答案
您的类 B 不会覆盖 A 中的成员函数,而是重载它。或者尝试无论如何,稍后再看关于隐藏的内容。
重写是指派生类从基类定义自己的虚拟成员函数版本。重载是当您定义具有相同名称的不同函数时。
当对具有基类类型的指针或引用进行虚拟调用时,它只会“考虑”派生类中的覆盖,而不是重载。这是必不可少的 - 对于 B 的实例,调用者将其视为 A 可以做的一切(这是动态多态性和虚函数的要点),它的 hello
函数需要能够接受类型 A 的任何对象。hello
函数只接受类型 B 的对象,而不是任何 A,限制性更强。它不能起到 A 的 hello
函数的作用,所以它不是覆盖。
如果您尝试在 A 和 B 上调用 hello
,传递 A 或 B 类型的对象,您应该能够看出区别。 A 有一个接受 A 的函数(你没有定义它,所以如果你调用它那么你的程序将无法链接,但你可以修复它)。 B 有一个接受 B 的函数。它们恰好具有相同的名称,当然,由于 B 派生自 A,您可以将 B 传递给接受 A 的函数。但是 B 的函数在虚拟调用中不充当重写.
可以在 B 对象上调用 A 的函数,但只能通过指向 A 的引用或指针。C++ 的一个特点是 B 中 hello
的定义隐藏了 A 中的定义。如果重载是你想要的,可以通过添加 using A::hello;
到类 B 来取消隐藏基类函数。如果你想要重载,你必须定义一个函数相同的参数。例如:
#include <iostream>
class A
{
public:
virtual int hello(A a) {std::cout << "A\n"; }
virtual int foo(int i) { std::cout << "A::Foo " << i << "\n"; }
};
class B : public A
{
public:
using A::hello;
// here's an overload
int hello(B b){ std::cout << "B\n"; };
// here's an override:
virtual int foo(int i) { std::cout << "B::Foo " << i << "\n"; }
};
int main() {
A a;
B b;
a.hello(a); // calls the function exactly as defined in A
a.hello(b); // B "is an" A, so this is allowed and slices the parameter
b.hello(a); // OK, but only because of `using`
b.hello(b); // calls the function exactly as defined in B
A &ab = b; // a reference to a B object, but as an A
ab.hello(a); // calls the function in A
ab.hello(b); // *also* calls the function in A, proving B has not overridden it
a.foo(1); // calls the function in A
b.foo(2); // calls the function in B
ab.foo(3); // calls the function in B, because it is overridden
}
输出:
A
A
A
B
A
A
A::Foo 1
B::Foo 2
B::Foo 3
如果您从 B 中删除 using A::hello;
行,则调用 b.hello(a);
将无法编译:
error: no matching function for call to `B::hello(A&)'
note: candidates are: int B::hello(B)
关于c++ - 虚函数和多态,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2440285/
C语言sscanf()函数:从字符串中读取指定格式的数据 头文件: ?
最近,我有一个关于工作预评估的问题,即使查询了每个功能的工作原理,我也不知道如何解决。这是一个伪代码。 下面是一个名为foo()的函数,该函数将被传递一个值并返回一个值。如果将以下值传递给foo函数,
CStr 函数 返回表达式,该表达式已被转换为 String 子类型的 Variant。 CStr(expression) expression 参数是任意有效的表达式。 说明 通常,可以
CSng 函数 返回表达式,该表达式已被转换为 Single 子类型的 Variant。 CSng(expression) expression 参数是任意有效的表达式。 说明 通常,可
CreateObject 函数 创建并返回对 Automation 对象的引用。 CreateObject(servername.typename [, location]) 参数 serv
Cos 函数 返回某个角的余弦值。 Cos(number) number 参数可以是任何将某个角表示为弧度的有效数值表达式。 说明 Cos 函数取某个角并返回直角三角形两边的比值。此比值是
CLng 函数 返回表达式,此表达式已被转换为 Long 子类型的 Variant。 CLng(expression) expression 参数是任意有效的表达式。 说明 通常,您可以使
CInt 函数 返回表达式,此表达式已被转换为 Integer 子类型的 Variant。 CInt(expression) expression 参数是任意有效的表达式。 说明 通常,可
Chr 函数 返回与指定的 ANSI 字符代码相对应的字符。 Chr(charcode) charcode 参数是可以标识字符的数字。 说明 从 0 到 31 的数字表示标准的不可打印的
CDbl 函数 返回表达式,此表达式已被转换为 Double 子类型的 Variant。 CDbl(expression) expression 参数是任意有效的表达式。 说明 通常,您可
CDate 函数 返回表达式,此表达式已被转换为 Date 子类型的 Variant。 CDate(date) date 参数是任意有效的日期表达式。 说明 IsDate 函数用于判断 d
CCur 函数 返回表达式,此表达式已被转换为 Currency 子类型的 Variant。 CCur(expression) expression 参数是任意有效的表达式。 说明 通常,
CByte 函数 返回表达式,此表达式已被转换为 Byte 子类型的 Variant。 CByte(expression) expression 参数是任意有效的表达式。 说明 通常,可以
CBool 函数 返回表达式,此表达式已转换为 Boolean 子类型的 Variant。 CBool(expression) expression 是任意有效的表达式。 说明 如果 ex
Atn 函数 返回数值的反正切值。 Atn(number) number 参数可以是任意有效的数值表达式。 说明 Atn 函数计算直角三角形两个边的比值 (number) 并返回对应角的弧
Asc 函数 返回与字符串的第一个字母对应的 ANSI 字符代码。 Asc(string) string 参数是任意有效的字符串表达式。如果 string 参数未包含字符,则将发生运行时错误。
Array 函数 返回包含数组的 Variant。 Array(arglist) arglist 参数是赋给包含在 Variant 中的数组元素的值的列表(用逗号分隔)。如果没有指定此参数,则
Abs 函数 返回数字的绝对值。 Abs(number) number 参数可以是任意有效的数值表达式。如果 number 包含 Null,则返回 Null;如果是未初始化变量,则返回 0。
FormatPercent 函数 返回表达式,此表达式已被格式化为尾随有 % 符号的百分比(乘以 100 )。 FormatPercent(expression[,NumDigitsAfterD
FormatNumber 函数 返回表达式,此表达式已被格式化为数值。 FormatNumber( expression [,NumDigitsAfterDecimal [,Inc
我是一名优秀的程序员,十分优秀!