不好意思,分散光了,等有分之后立马就给。
废话少说,先看一个简单的C++程序:
#include <iostream>
using namespace std;class myFirst
{
public:
void funcA()
{
cout<<"这是myFirst类的非虚拟函数\n";
}
virtual void funcB()
{
cout<<"这是myFirst类的虚拟函数\n";
}
};
class mySecond : public myFirst
{
public:
void funcA()
{
cout<<"这是mySecond类的非虚拟函数\n";
}
virtual void funcB()
{
cout<<"这是mySecond类的虚拟函数\n";
}
}; int main()
{
mySecond bb;
① bb.funcA();
② bb.funcB();
③ ((myFirst*)(&bb))->funcA();
④ ((myFirst*)(&bb))->funcB();
⑤ ((myFirst)(bb)).funcA();
⑥ ((myFirst)(bb)).funcB();
return 0;
}
1和2的输出就不说了,很明确;5和6是向上强制转型(upcasting),将会造成对象的内容被切割;小弟不明白3和4的输出,主要就是(myFirst*)(&bb)这个表达式(我理解是把bb的地址形式转换为myFirst的地址形式),这个表达式对bb的内容有什么样的影响,对于输出的原因不太清楚,烦请各位高手解答一下,最好能从本质上解释。整个程序的输出结果如下所示:这是mySecond类的非虚拟函数
这是mySecond类的虚拟函数
这是myFirst类的非虚拟函数
这是mySecond类的虚拟函数
这是myFirst类的非虚拟函数
这是myFirst类的虚拟函数
****************************************** 下面是同样内容的C#程序:
using System;
using System.Collections.Generic;
using System.Text;namespace 虚函数测试Cs
{
public class myFirst
{
public void funcA()
{
Console.WriteLine("这是myFirst类的非虚拟函数");
}
public virtual void funcB()
{
Console.WriteLine("这是myFirst类的虚拟函数");
}
};
public class mySecond : myFirst
{
new public void funcA()
{
Console.WriteLine("这是mySecond类的非虚拟函数");
}
public override void funcB()
{
Console.WriteLine("这是mySecond类的虚拟函数");
}
};
class Program
{
static void Main(string[] args)
{
mySecond bb = new mySecond();
① bb.funcA();
② bb.funcB();
③ ((myFirst)(bb)).funcA();
④ ((myFirst)(bb)).funcB();
}
}
}
1和2的输出很明确,不说了。
C# 和C++在类对象赋值运算符(=)这个地方不一样,C++是对象的复制,而在C#中,”=”复制它的引用,即地址,而不是复制对象。例如有一个类A ,在C++中, 代码A a;A b=a;是生成了两个类对象a和b,且这两个对象里面的数据成员的值应该是一样的,而在C#中,代码 A a = new A();A b=a;运行之后,b和a其实指向的地址是同样的,b只是a的一个引用。所以从这个角度来讲,我觉得在C#中,(myFirst)(bb)应该和C++中的(myFirst*)(&bb)在本质上是一样的,经验证,本程序中的3和4与C++程序中的3和4的输出结果是统一的。
本程序输出如下:
这是mySecond类的非虚拟函数
这是mySecond类的虚拟函数
这是myFirst类的非虚拟函数
这是mySecond类的虚拟函数
**********************************************
下面是同样内容的Java程序:
class myFirst
{
public void funcA()
{
System.out.println("这是myFirst类的非虚拟函数");
}
}
class mySecond extends myFirst
{
public void funcA()
{
System.out.println("这是mySecond类的非虚拟函数");
}
}public class test {
public static void main(String[] args) {
mySecond bb=new mySecond();
① bb.funcA();
② ((myFirst)bb).funcA();
}
}
由于Java中没有虚拟函数,所以只能测试一下函数覆盖的情况。Java和C#类似,”=”复制类对象之间的地址,我原本以为1和2的输出应该和C#程序中的3和4的输出统一,不过结果却出乎我的意料,程序的输出如下:
这是myFirst类的非虚拟函数
这是myFirst类的非虚拟函数
所以小弟的第二个问题是这个Java程序这样输出的原因。另外,我刚刚学Java,看代码看的不是很多,但似乎没有见到Java中有(myFirst)bb这样的用法,是不是Java把C++中一切可能导致歧义的用法都抛弃不用了?呵呵,纯属瞎想,还请高手指出真正的原因。
废话少说,先看一个简单的C++程序:
#include <iostream>
using namespace std;class myFirst
{
public:
void funcA()
{
cout<<"这是myFirst类的非虚拟函数\n";
}
virtual void funcB()
{
cout<<"这是myFirst类的虚拟函数\n";
}
};
class mySecond : public myFirst
{
public:
void funcA()
{
cout<<"这是mySecond类的非虚拟函数\n";
}
virtual void funcB()
{
cout<<"这是mySecond类的虚拟函数\n";
}
}; int main()
{
mySecond bb;
① bb.funcA();
② bb.funcB();
③ ((myFirst*)(&bb))->funcA();
④ ((myFirst*)(&bb))->funcB();
⑤ ((myFirst)(bb)).funcA();
⑥ ((myFirst)(bb)).funcB();
return 0;
}
1和2的输出就不说了,很明确;5和6是向上强制转型(upcasting),将会造成对象的内容被切割;小弟不明白3和4的输出,主要就是(myFirst*)(&bb)这个表达式(我理解是把bb的地址形式转换为myFirst的地址形式),这个表达式对bb的内容有什么样的影响,对于输出的原因不太清楚,烦请各位高手解答一下,最好能从本质上解释。整个程序的输出结果如下所示:这是mySecond类的非虚拟函数
这是mySecond类的虚拟函数
这是myFirst类的非虚拟函数
这是mySecond类的虚拟函数
这是myFirst类的非虚拟函数
这是myFirst类的虚拟函数
****************************************** 下面是同样内容的C#程序:
using System;
using System.Collections.Generic;
using System.Text;namespace 虚函数测试Cs
{
public class myFirst
{
public void funcA()
{
Console.WriteLine("这是myFirst类的非虚拟函数");
}
public virtual void funcB()
{
Console.WriteLine("这是myFirst类的虚拟函数");
}
};
public class mySecond : myFirst
{
new public void funcA()
{
Console.WriteLine("这是mySecond类的非虚拟函数");
}
public override void funcB()
{
Console.WriteLine("这是mySecond类的虚拟函数");
}
};
class Program
{
static void Main(string[] args)
{
mySecond bb = new mySecond();
① bb.funcA();
② bb.funcB();
③ ((myFirst)(bb)).funcA();
④ ((myFirst)(bb)).funcB();
}
}
}
1和2的输出很明确,不说了。
C# 和C++在类对象赋值运算符(=)这个地方不一样,C++是对象的复制,而在C#中,”=”复制它的引用,即地址,而不是复制对象。例如有一个类A ,在C++中, 代码A a;A b=a;是生成了两个类对象a和b,且这两个对象里面的数据成员的值应该是一样的,而在C#中,代码 A a = new A();A b=a;运行之后,b和a其实指向的地址是同样的,b只是a的一个引用。所以从这个角度来讲,我觉得在C#中,(myFirst)(bb)应该和C++中的(myFirst*)(&bb)在本质上是一样的,经验证,本程序中的3和4与C++程序中的3和4的输出结果是统一的。
本程序输出如下:
这是mySecond类的非虚拟函数
这是mySecond类的虚拟函数
这是myFirst类的非虚拟函数
这是mySecond类的虚拟函数
**********************************************
下面是同样内容的Java程序:
class myFirst
{
public void funcA()
{
System.out.println("这是myFirst类的非虚拟函数");
}
}
class mySecond extends myFirst
{
public void funcA()
{
System.out.println("这是mySecond类的非虚拟函数");
}
}public class test {
public static void main(String[] args) {
mySecond bb=new mySecond();
① bb.funcA();
② ((myFirst)bb).funcA();
}
}
由于Java中没有虚拟函数,所以只能测试一下函数覆盖的情况。Java和C#类似,”=”复制类对象之间的地址,我原本以为1和2的输出应该和C#程序中的3和4的输出统一,不过结果却出乎我的意料,程序的输出如下:
这是myFirst类的非虚拟函数
这是myFirst类的非虚拟函数
所以小弟的第二个问题是这个Java程序这样输出的原因。另外,我刚刚学Java,看代码看的不是很多,但似乎没有见到Java中有(myFirst)bb这样的用法,是不是Java把C++中一切可能导致歧义的用法都抛弃不用了?呵呵,纯属瞎想,还请高手指出真正的原因。
解决方案 »
免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货