zoukankan      html  css  js  c++  java
  • C++中子类的数组不能用父类指针来表示

    假设我们有一个父类A,一个子类B,如果我们创建一个B的数组,我们能这样用吗?

    A* barray = new B[10];

    写段代码在Visual Studio中来试试吧:)

     1 #include <iostream>
     2 #include <assert.h>
     3 
     4 using namespace std;
     5 class B;
     6 class A
     7 {
     8 public:
     9     A();
    10     ~A();
    11     int aa;
    12 };
    13 
    14 class B:public A
    15 {
    16 public:
    17     B();
    18     ~B();
    19     int bb;
    20 };
    21 
    22 A::A()
    23 {
    24     cout<<"A"<<" ";
    25     aa=1;
    26 }
    27 
    28 A::~A()
    29 {
    30     cout<<"~A"<<" ";
    31     aa=-1;
    32 }
    33 
    34 B::B()
    35 {
    36     cout<<"B"<<" ";
    37     bb=2;
    38 }
    39 
    40 B::~B()
    41 {
    42     cout<<"~B"<<" ";
    43 
    44     bb=-2;
    45 }
    46 
    47 int main(int argc, char* argv[])
    48 {
    49     cout<<"size of A: "<<sizeof(A)<<endl;
    50     cout<<"size of B: "<<sizeof(B)<<endl;
    51     A* aarray = new B[10];
    52 
    53     cout<<endl<<endl<<"aa value of A* is:"<<endl;
    54     for (int i = 0; i < 10; i++)
    55     {
    56         cout<<aarray[i].aa<<", ";
    57     }
    58     cout<<endl;
    59 
    60     B* baaray = (B*)aarray;
    61     cout<<endl<<"aa value of B* is:"<<endl;
    62     for (int i = 0; i < 10; i++)
    63     {
    64         cout<<baaray[i].aa<<", ";
    65     }
    66     cout<<endl<<endl;
    67 
    68     delete[] aarray;
    69     cout<<endl<<endl<<"After delete[]"<<endl;
    70 
    71     cout<<endl<<"aa value of A* is:"<<endl;
    72     for (int i = 0; i < 10; i++)
    73     {
    74         cout<<aarray[i].aa<<", ";
    75     }
    76     cout<<endl;
    77     baaray = (B*)aarray;
    78     cout<<endl<<"aa value of B* is:"<<endl;
    79     for (int i = 0; i < 10; i++)
    80     {
    81         cout<<baaray[i].aa<<", ";
    82     }
    83     return 0;
    84 }

    我们可以看到输出的结果是:

    size of A: 4
    size of B: 8
    A B A B A B A B A B A B A B A B A B A B
    
    aa value of A* is:
    1, 2, 1, 2, 1, 2, 1, 2, 1, 2,
    
    aa value of B* is:
    1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
    
    ~A ~A ~A ~A ~A ~A ~A ~A ~A ~A
    
    After delete[]
    
    aa value of A* is:
    4408224, -1, -1, -1, -1, -1, -1, -1, -1, -1,
    
    aa value of B* is:
    4408224, -1, -1, -1, -1, 1, 1, 1, 1, 1, 

    说明尽管我们创建时用的是new B,但是因为声明的是A*,所以被认为是一个A的数组,按照A的大小来操作,所以可以看到成员变量aa的值是不对的。而且最后析构的时候只调用了A的析构函数,说明这个数组在delete的时候也是有问题的。

    如果我们把A的析构函数加上virtual,可以得到如下的结果:

    size of A: 8
    size of B: 12
    A B A B A B A B A B A B A B A B A B A B
    
    aa value of A* is:
    1, 668240, 2, 1, 668240, 2, 1, 668240, 2, 1,
    
    aa value of B* is:
    1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
    
    ~B ~A ~B ~A ~B ~A ~B ~A ~B ~A ~B ~A ~B ~A ~B ~A ~B ~A ~B ~A
    
    After delete[]
    
    aa value of A* is:
    -1, 668248, -2, -1, 668248, -2, -1, 668248, -2, -1,
    
    aa value of B* is:
    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,

    说明只要我们加上virtual,在delete的时候编译器是知道怎么delete的。

    但是这并不是C++标准中制定的,不同的编译器会有不同的结果,比如如果把带virtual的代码放在g++中,会得到如下的结果:

    size of A: 8
    size of B: 12
    A B A B A B A B A B A B A B A B A B A B 
    
    aa value of A* is:
    1, 134540944, 2, 1, 134540944, 2, 1, 134540944, 2, 1, 
    
    aa value of B* is:
    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
    
    
    Segmentation fault

    所以,C++中子类的数组不能用父类指针来表示。

  • 相关阅读:
    freemarker.core.ParseException:Unexpected end of file reached
    freemarker.template.TemplateException:Error executing macro:mainSelect
    Perl--子程序传参
    MFC管理员权限(UAC下的程序权限提升)
    高级编程
    vmstat 查看堵塞的队列
    linux crontab 文件位置和日志位置
    linux 定时执行shell脚本 crontab
    Redis 命令参考 » Server(服务器)
    AiX--Ipcs 资源
  • 原文地址:https://www.cnblogs.com/fresky/p/2800274.html
Copyright © 2011-2022 走看看