程序员面试宝典3TH-ch7.2

下列程序的输出结果是什么?

#include "stdafx.h"

#include <iostream>
using namespace std;

class A
{
public:
    int _a;
    A()
    {
        _a = 1;
    }
    void print()
    {
          cout << _a << endl;
    }
};
class B : public A
{
public:
    int _a;
    B()
    {
        _a = 2;
    }
};
int _tmain(int argc, _TCHAR* argv[])
{
    B b;
    b.print();
    cout<<b._a<<endl;
    system("pause");
    return 0;
}

结果:

image

一开始很容易会误以为是22

首先,我们来看一下什么时候,输出会是22呢?

只要把B中_a定义这一行注释掉,就会是22了,至于为什么,对于一开始以为答案是22的朋友,显而易见。

那么为什么题中会是12呢?

我们可以将A,B两个类的大小(对象大小)输出:

int _tmain(int argc, _TCHAR* argv[])
{
    cout<<sizeof(A)<<endl;
    cout<<sizeof(B)<<endl;
    
    B b;
    b.print();
    cout<<b._a<<endl;
    system("pause");
    return 0;
}

image

可以看到,B的大小是A的2倍,这是因为在B中有两个int型变量:

A::_a

B::_a

如果我们在开始的地方加上断点调试就会发现,在B类实例初始化的时候,首先会把A::_a赋值为1,然后把B::_a赋值为2,而当执行print的时候,实际上是进入A中:

image

所以输出的当然是A::_a,实际上,如果把B中,定义_a的一行去掉,依然输出的是A::_a,如果想要输出B::_a,只有在B中增加print(),才行,而且此时输出的就会是22。

还有一题:

这个是从http://bbs.csdn.net/topics/330161711这里copy的,不过讲的挺好的

struct S
{
int i;
int *p;
};

main()
{
S s;
int *p = &s.i;
p[0] = 4; //把i的值改为4
p[1] = 3;//这个地方越界写了,把保存在int i下面的指针int* p的值给写为3了
s.p = p; //又把这个结构体s中指针p的值赋为上面int i的地址
s.p[1] = 1;//i下面的指针指向i的地址,现在把自身修改为1了
s.p[0] = 2;//再访问内容为1的指针所指空间就出错了,这行崩溃了
}

 

转载于:https://www.cnblogs.com/marsdu/p/3296583.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值