【C++】const和引用的关系(2)。

1、引用的特殊用法

1 基础回顾

int main()
{
    int a = 10;
    const int b = 20;
    
    //针对整型a
    int &c1 = a;
 	const int &c2 = a;
    a = 2000;				//可以通过a修改c2的值
    cout <<" a = "<< a << endl;
    cout <<" c1 = "<<c1 << endl;
    cout <<" c2 = "<<c2 << endl;
    
  
    
    //针对整型常量b
    int &c3 = b;		//error,常变量只能常引用
    const int &c4 = b;
    
    return 0;
}

运行结果:

在这里插入图片描述
总结:

普通变量可以普通引用,也可以常引用。

常变量只能常引用。

2 字面值常量

定义一个常引用b作为a的别名,定义一个常引用c来作为字面常量10的别名。定义一个整型引用d来作为字面常量10的别名。

int main()
{
    int a = 10;
    const int &b = a;
    //上面一行代码相当于
    //const int *const b = &a;
    
    const int &c = 10;
    //上面一行代码相当于
    //int tmp = 10;
    //const int &c = &tmp;
    //const int * const c = &tmp;
    
    int &d = 10;	//error
    
    return 0;
}

总结:常引用直接引用字面常量,普通引用不能直接引用字面常量。

问题:思考下面两种方式的底层是否一样?

回答:不一样

    const int a = 10;
    const int &b = a;
    //上面两行相当于
    //const int a = 10;
    //const int *const b = &a;

    const int &c = 10;
    //上面一行相当于
    //int temp = 10;
    //const int *cosnt c = &temp; 

VS2019生成反汇编如下:

    const int a = 10;
000D1832  mov         dword ptr [a],0Ah  
    const int& b = a;
000D1839  lea         eax,[a]  
000D183C  mov         dword ptr [b],eax  
    const int& c = 10;
000D183F  mov         dword ptr [ebp-30h],0Ah  
000D1846  lea         eax,[ebp-30h]  
000D1849  mov         dword ptr [c],eax  

在这里插入图片描述

总结:从上述可以看出来,常引用引用字面值和普通变量引用的时候是有区别的。

常引用引用字面值需要先构造一个临时量来存储字面值。

3 存储对象数组

静态创建对象数组:

class Object
{
    int value;
public:
    Object(int x = 0) : value(x)    
    {
        cout << "create:" << this << endl;
    }
    void Print() const 
    {
        cout << value << endl;
    }
    ~Object()   
    {
        cout << "~Object:" << this <<endl;
    }
};

Object obj3(4);

int main()
{
    Object obj[10];
    return 0;
}

g++输出结果:

create:0x407030
create:0x61fdd0
create:0x61fdd4
create:0x61fdd8
create:0x61fddc
create:0x61fde0
create:0x61fde4
create:0x61fde8
create:0x61fdec
create:0x61fdf0
create:0x61fdf4
~Object:0x61fdf4
~Object:0x61fdf0
~Object:0x61fdec
~Object:0x61fde8
~Object:0x61fde4
~Object:0x61fde0
~Object:0x61fddc
~Object:0x61fdd8
~Object:0x61fdd4
~Object:0x61fdd0
~Object:0x407030

使用指针动态创建对象数组:

int main()
{
    int n;
    cin >> n;	//变量
    Object *s = new Object(n);	//只有一个对象,调用构造函数
    Object *p = new Object[n];	//一组对象
    
    //不要忘记释放空间
    delete[] p;					//加方括号释放一组对象。
    delete s;
    return 0;
}

问题1:构造一组对象的时候,如果没有缺省构造函数,会发生什么?

回答:报错

class Object
{
    int value;
public:
    Object(int x) : value(x)                //将默认参数删除
    {
        cout << "create:" << this << endl;
    }
    void Print() const 
    {
        cout << value << endl;
    }
    ~Object()   
    {
        cout << "~Object:" << this <<endl;
    }
};

Object obj3(4);

int main()
{
    int n;
    cin >> n;	//变量
    Object *s = new Object(n);	//只有一个对象,调用构造函数
    Object *p = new Object[n];	//一组对象
    
    //不要忘记释放空间
    delete[] p;					//加方括号释放一组对象。
    delete s;
    return 0;
}

编译运行:

error: no matching function for call to ‘Object::Object()’

没有找到构造函数

问题2:能否通过 Object *p = new Object[n] (23)这样使用 ?意思是每个对象都有23来初始化。

回答:报错

class Object
{
    int value;
public:
    Object(int x) : value(x)                //将默认参数删除
    {
        cout << "create:" << this << endl;
    }
    void Print() const 
    {
        cout << value << endl;
    }
    ~Object()   
    {
        cout << "~Object:" << this <<endl;
    }
};

Object obj3(4);

int main()
{
    int n;
    cin >> n;	//变量
    Object *s = new Object(n);	//只有一个对象,调用构造函数
    Object *p = new Object[n](23);	//一组对象,想使用23初始化
    
    //不要忘记释放空间
    delete[] p;					//加方括号释放一组对象。
    delete s;
    return 0;
}

编译:

error: parenthesized initializer in array new Object *p = new Object n;

数组初始化时对象带new。

注意:编写类型时,必须要创建一个缺省的构造函数,否则无法创建一组对象。

总结:

可以通过new来创建一组对象,但是不要忘记最后释放对象空间。

编写类型时,必须要创建一个缺省的构造函数,否则无法创建一组对象。

4 new 的另一个用法

下次更新

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值