【C++零散】类中特殊的成员变量(常变量、引用、静态)的初始化方法

1. 类中成员变量是引用

不能有默认构造函数,必须提供构造函数

  • 凡是有引用类型的成员变量的类,不能有缺省构造函数。默认构造函数没有对引用成员提供默认的初始化机制,也因此造成引用未初始化的编译错误。

初始化必须在成员初始化链表内完成

  • 不能直接在构造函数里初始化,必须用到初始化列表,且形参也必须是引用类型。构造函数分为初始化和计算两个阶段,前者对应成员初始化链表,后者对应构造函数函数体。引用必须在初始化阶段,也即在成员初始化链表中完成,否则编译时会报错(引用未初始化)。
#include <iostream>

using namespace std;

class Ref
{
public:
    // 构造函数形参为传值,不能保证正确性
    // Ref (int target) :myref(target) {
    // cout << "Ref constructor" << endl;
    // }

    // 函数体对引用赋值,编译错误:引用未初始化
    // Ref (int &target)  {
    // myref = target;
    // cout << "Ref constructor" << endl;
    // }

    // 如果成员为变量为引用类型,那么构造函数的参数为应用类型
    // 引用必须在成员初始化链表里面初始化,不能在函数体里面初始化
    // 在函数体里面修改myref,相当于赋值,显然引用不能赋值
    Ref(int &target) : myref(target)
    {
        cout << "Ref constructor" << endl;
    }

    void printRef()
    {
        cout << "myref is: " << myref << endl;
    }

    virtual ~Ref() {}

private:
    int &myref;
    /* data */
};

int main(int argc, char *argv[])
{
    int a = 20;
    Ref r(a);
    r.printRef();

    int &b = a;
    Ref r1(b);
    r1.printRef();

    // error:引用定义时必须初始化
    // int &c;

    return 0;
}

2. 类中成员变量是常变量、引用、静态

  1. 静态成员属于类作用域,但不属于类对象,和普通的static变量一样,程序一运行就分配内存并初始化,生命周期和程序一致。所以,在类的构造函数里初始化static变量显然是不合理的。
  2. 静态成员其实和全局变量地位是一样的,只不过编译器把它的使用限制在类作用域内(不是类对象,它不属于类对象成员),要在类的定义外(不是类作用域外)初始化
  3. 静态成员在类的所有对象中是共享的。如果不存在其他的初始化语句,在创建第一个对象时,所有的静态数据都会被初始化为零。我们不能把静态成员的初始化放置在类的定义中,但是可以在类的外部通过使用范围解析运算符 :: 来重新声明静态变量从而对它进行初始化,如下面的实例所示。
#include <iostream>
using namespace std;

class BClass
{
public:
    BClass() : i(1), ci(2), ri(i) {} // 对于常量型成员变量和引用型成员变量,必须通过参数化列表的方式进行初始化
                                     //普通成员变量也可以放在函数体里,但是本质其实已不是初始化,而是一种普通的运算操作-->赋值运算,效率也低
private:
    int i;         // 普通成员变量
    const int ci;  // 常量成员变量
    int &ri;       // 引用成员变量
    static int si; // 静态成员变量
    // static int si2 = 100;                 // error: 只有静态常量成员变量,才可以这样初始化
    static const int csi;        // 静态常量成员变量
    static const int csi2 = 100; // 静态常量成员变量的初始化(Integral type)    (1)
    static const double csd;     // 静态常量成员变量(non-Integral type)
    // static const double csd2 = 99.9;      // error: 只有静态常量整型数据成员才可以在类中初始化
};

//注意下面三行:不能再带有static
int BClass::si = 0;              // 静态成员变量的初始化(Integral type)
const int BClass::csi = 1;       // 静态常量成员变量的初始化(Integral type)
const double BClass::csd = 99.9; // 静态常量成员变量的初始化(non-Integral type)

// 在初始化(1)中的csi2时,根据著名大师Stanley B.Lippman的说法下面这行是必须的。
// 但在VC2003中如果有下面一行将会产生错误,而在VC2005中,下面这行则可有可无,这个和编译器有关。
const int BClass::csi2;

int main()
{
    BClass b;
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

宇光_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值