zoukankan      html  css  js  c++  java
  • 为什么子类的初始化列表不能初始化父类的成员

    为什么子类的初始化列表不能初始化父类的成员

    • C++初始化列表是一种效率更高的初始化方法,但也有一些不能使用的场景。

    举个例子

    • 以下定义一个矩形,然后再定义一个正方形,继承自矩形。
    • 这段代码有问题吗?
    ...
    class Rectangle{
    public:
    	Rectangle() :a(0), b(0){}
    	Rectangle(int x, int y) :a(x), b(y){}
    
    public:
    	int a;
    	int b;
    };
    class Square :public Rectangle
    {
    public:
    	Square(int x):a(x) {}
    };
    ...
    
    • 是的,这段代码是无法编译通过的。Vs中报错如下:
    error C2614: “Square”: 非法的成员初始化:“a”不是基或成员
    
    • 虽然乍一看没毛病,继承是public继承,构造是父类先构造,但为什么子类用初始化列表时会报错呢?
    • 而将子类的构造函数改成下面这样,竟然就可以了。它们明明看起来一样啊?
    ...
    Square(int x)
    {
        a = x;
    }
    ...
    

    查找原因

    • 这就要探讨以下初始化列表和普通初始化的区别。
    • 编译器在检查列表初始化时,大概经过了这样一个过程:
    子类:来来来,父类,你先构造
    父类:好,我的成员a和b还没定义,那就用初始化列表(int a=0,int b=0)来初始化,构造完毕。
    子类:轮到我构造了,我的成员里没有a,我也用的是初始化列表(int a=x),所以我也来int a=x,咦,好像不对,我的成员里没有a啊?(可是如果父类里a我继承的话,为什么主人要用初始化列表(int a=x)再来定义一次a呢?)
    
    • 编译器不知道怎么处理了,只能告诉你,这个语法不对。
    • 而将子类初始化放在构造函数内部,则是这样一个过程:
    子类:来来来,父类,你先构造
    父类:好,我的成员a和b还没定义,那就用初始化列表(int a=0,int b=0)来初始化,构造完毕。
    子类:轮到我构造了,我用的是赋值初始化(a=x),当然也要先看下有没有a,正好有(从父类继承的),执行a=x,初始化好了。
    
    • 看到不同了吗?在构造时,初始化列表会将成员定义和赋值优化到一步里。这正是为何无法使用子类初始化列表初始化父类成员,也是初始化列表效率高的原因,因为初始化列表节省了一步操作。
  • 相关阅读:
    MFC中char*,string和CString之间的转换
    图像分割之(四)OpenCV的GrabCut函数使用和源码解读
    自然图像抠图/视频抠像技术发展情况梳理
    OpenCV混合高斯模型函数注释说明
    Effective STL 为包含指针的关联容器指定比较类型
    vs2010修改状态栏的CStatusBar指针的的SetPaneText()方法时死活不对问题
    windows c/c++ 代码运行时间,毫秒级
    【Math】根据置信度、样本数相关推导过程
    宝宝加减法出题小程序
    混淆矩阵
  • 原文地址:https://www.cnblogs.com/linkyip/p/8418319.html
Copyright © 2011-2022 走看看