目录
代码执行后,a和b的值分别为?
- #include
-
- using namespace std;
- class Test{
- public:
- int a;
- int b;
- virtual void fun() {}
- Test(int temp1 = 0, int temp2 = 0)
- {
- a=temp1 ;
- b=temp2 ;
- }
- int getA()
- {
- return a;
- }
- int getB()
- {
- return b;
- }
- };
- int main()
- {
- Test obj(5, 10);
- // Changing a and b
- int* pInt = (int*)&obj;
- *(pInt+0) = 100;
- *(pInt+1) = 200;
- cout << "a = " << obj.getA() << endl;
- cout << "b = " << obj.getB() << endl;
- return 0;
- }
A 200 10
B 5 10
C 100 200
D 100 10
首先我们创建了一个Test类型的对象,然后将其地址强制转换成int*赋值给了pInt,也就是得到了起始位置的4个字节的地址(32)位
如果没有虚函数的话,也就是将下面这行代码注释掉
我们的a和b刚好是在我们的对象前面的两个成员,
所以*(pInt+0)其实就是我们的a的值,我们将其修改为100
*(pInt+1)其实就是我们的b的值,我们将其修改为200
但是有了这里的虚函数的话
我们的对象的首位置是我们的虚表指针
然后+1之后的修改,实际上修改的是我们的a成员
也就是我们这里将我们的虚表赋值为了100,然后将我们的a成员赋值为了200
然后我们的b成员还是原来的10
由于这里没有访问虚函数,所以没有报错,但实际上如果通过多态访问虚函数表,就会报错,因为我们的虚表指针已经不能找到我们正确的虚表了
A
下列程序的输出结果:
- #include
- using namespace std;
- class A
- {
- public:
- void print()
- {
- cout << "A:print()";
- }
- };
- class B: private A
- {
- public:
- void print()
- {
- cout << "B:print()";
- }
- };
- class C: public B
- {
- public:
- void print()
- {
- A:: print();
- }
- };
- int main()
- {
- C b;
- b.print();
- }
A A:print()
B B:print()
C 编译出错
B继承A,但是一个私有继承
C共有继承B
我们这里创建了一个C的对象,想要去调用A的方法
程序会出错,因为B私有继承A,那么A中的所用成员在B中表现为私有成员
那我们的C类是B类的子类,子类没有办法访问父类的私有成员。
C
下面关于多态性的描述,错误的是()
A C++语言的多态性分为编译时的多态性和运行时的多态性
B 编译时的多态性可通过函数重载实现
C 运行时的多态性可通过模板和虚函数实现
D 实现运行时多态性的机制称为动态绑定
C中的模板和多态没有关系,模板是为了实现泛型编程,这两个不是同一个机制
C
写出下面程序的输出结果
- #include
- class A
- {
- public:
- void FuncA()
- {
- printf( "FuncA called\n" );
- }
- virtual void FuncB()
- {
- printf( "FuncB called\n" );
- }
- };
- class B : public A
- {
- public:
- void FuncA()
- {
- A::FuncA();
- printf( "FuncAB called\n" );
- }
- virtual void FuncB()
- {
- printf( "FuncBB called\n" );
- }
- };
- void main( void )
- {
- B b;
- A *pa;
-
- pa = &b;
- A *pa2 = new A;
- pa->FuncA(); //( 3)
- pa->FuncB(); //( 4)
- pa2->FuncA();//( 5)
- pa2->FuncB();
- delete pa2;
- }
A FuncA called FuncB called FuncA called FuncB called
B FuncA called FuncBB called FuncA called FuncB called
C FuncA called FuncBB called FuncAB called FuncBB called
D FuncAB called FuncBB called FuncA called FuncB called
创建一个子类对象b
父类指针指向子类对象pa
父类指针指向父类对象pa2
pa->FuncA()由于我们的pa是父类指针指向子类对象,但是父类的FuncA()中并没有写virtual,所以不满足多态的条件,直接调用父类的FuncA()方法,打印FuncA called
pa->FuncB()由于这里是父类的指针指向子类的对象并且父类中的FuncB前面有virtual,满足多态的条件,所以我们这里直接调用子类的FuncB,打印FuncBB called
pa2->FuncA 这里的pa2是父类的指针指向父类的对象,所以它是直接调用父类的FuncA方法,打印FuncA called
pa2->FuncB 这里的pa2是父类的指针指向父类的对象,不满足多态的条件,所以它是直接调用父类的FuncB方法,打印FuncB called
B
- #include
- using namespace std;
- class Base
- {
- public:
- virtual int foo(int x)
- {
- return x * 10;
- }
- int foo(char x[14])
- {
- return sizeof(x) + 10;
- }
- };
- class Derived: public Base
- {
- int foo(int x)
- {
- return x * 20;
- }
- virtual int foo(char x[10])
- {
- return sizeof(x) + 20;
- }
- } ;
- int main()
- {
- Derived stDerived;
- Base *pstBase = &stDerived;
- char x[10];
- printf("%d\n", pstBase->foo(100) + pstBase->foo(x));
- return 0;
- }
在32位环境下,以上程序的输出结果是?
A 2000
B 2004
C 2014
D 2024
我们首先创建了一个子类对象,然后用父类的指针指向子类的对象
父类的指针访问foo(100),这里满足了多态调用的条件,调用的是子类的方法,也就是我们下面两个中,更下面的这个方法
100*20=2000
这里只要传入一个指针数组就可以调用这个方法,跟你是不是14没有关系
这里我们是父类的指针,并且不满足多态的条件,所以我们直接调用的就是父类的foo方法。因为我们在32位的系统下,我们的指针的大小为4个字节,所以这里返回的是
4+10=14
最后我们将这两个值加起来也就是2000+14=2014
C