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 的另一个用法
下次更新