C++(11后才有的特性)中通用初始化语法(universal initialization)的使用用法

universal initialization语法使得C++对变量对象的定义和初始化与C相比发生了明显的变化,更加方便与灵活。

如下代码所示:

--------cpp---------
    int(1);
    int x(1);
    int{1};
    int x3{2};
    int x1[5]{1,2,3,4,5};
    auto *p = new int[3]{1, 2};

这些语法在c语言中都是不成立的,但是再c++中都是可以的。

用()和{}等价于在C中的=号操作;

()是给基本类型变量用来初始化,{}是用来给自定义或官方的类(也是一种类型,不过不是基本类型)的对象初始化,{}包含了(),可以用()初始化的地方都可以用{}代替,但是{}不能用()代替。

格式:基本类型() 就可以表示申请了一个基本类型大小的内存,不用向C中那样必须要一个变量名,如下:

--------cpp---------
    int();	   //没有变量名,就向内存中申请了一块空间,没有初始化
    int(1);    //没有变量名,就向内存中申请了一块空间,初始化为1
    int x(1);  //也可以用变量名向内存中申请一块空间,初始化为1
    int{1};
    int x3{2};

格式:类名 {} 表示申请了一个类大小的内存(这里的类就相当于自定义的类型),与c中相似的语法就是结构体

如下代码:
首先定义了一个point类

#include <iostream>
#include <string>
#include<vector>
using namespace std;
struct point
{
    int x;
    int y;
    point() = default;
    point(int z) : x{z}, y(z){
        cout << "initial construct\n";
    };
    point(point &p)
    {
        cout << "copy construct\n";
    }

};

使用代码:

point ();//没有对象名,申请了一个point类大小的内存,调用了缺省构造函数初始化,一般
point p(); //有对象名,申请了一个point类大小的内存,调用了缺省构造函数初始化
point {};
point p4{};
point {4};//没有对象名,申请了一个point类大小的内存,调用了参数构造函数point(int z)初始化
point p6{4};//有对象名,申请了一个point类大小的内存,调用了参数构造函数point(int z)初始化
auto *p2 = new point[3]{1, 2};
point[3]{1, 2};//申请数组这种形式是错的,必须加上数组名,上面用new的也可以

point p6{4,2};使用这种形式初始化,如果类point中什么构造函数都没有,则该初始化直接对公共区域的成员变量赋值

struct point
{
    int x;
    int y;
   //这里什么构造函数都没有,复制,析构都没

};

point p6{42};//4赋给x,2赋给y

如果point类中有复制构造函数,则是调用复制构造函数来赋值(这个时候就相当于将大括号变为小括号,与调用构造函数一样),如下:

struct point
{
    int x;
    int y;
    point(int z):x(z),y{z}{}//这里构造函数的参数列表里用{}就是赋值

};

point p6{4};//4赋给z,z赋给x和y.   

一般没有变量名或对象名的操作使用在返回值return ,
其它地方还是要有名字来操作。

一.返回值中的使用

直接在类型的后面接上一对大括号,大括号里面写每个构造函数参数的值,或者没有构造函数的情况下写每个成员变量的值,然后这一个整体就构成一个表达式,返回一个这个类型的实例.

Vector operator+(Vector a,Vector b)
{
    return Vector{a.x+b.x,a.y+b.y};//没有对象名,但是已经生成了一个对象
}

如果上述不用{}通用初始化语法,则需要在函数中实例化一个对象,最后return这个对象。如下: 显然这种方法较为麻烦。

Vector operator+(Vector a,Vector b)
{
	Vector c;
	c.x=a.x+b.x;
	c.y=a.y+b.y;
    return c;
}

这里边有个小bug,返回类的对象时应该会调用复制构造函数,但是这里没有
引申一下:
一般有三种情况会调用复制构造函数:
1.当用类一个对象去初始化另一个对象时。point a = b;或point a(b);

2.如果函数形参是类对象。void test(point p){}

3.如果函数返回值是类对象,函数执行完成返回调用时。

point test()
{   
	point p;
	return p ;
}

point test()
{   
	
	return point{} ;
}

前两种经过测试都会调用复制构造函数,维度第三个不行。后查找资料得到结果:
参考文章

2.类的实例化对象初始化

下图代码
Point a{1,2}; 就直接将类的成员变量进行了初始化;

如果不用{}通用初始化语法,用如下语法:
Point a(1,2);也可以初始化,这个时候调用的是类的构造函数对它初始化,在类中要写好构造函数才行。

#include <iostream>
#include <string>
using namespace std;

/* 请在这里定义struct */
struct Point
{
    int x;
    int y;
};
struct Vector
{
    int x;
    int y;
};

Vector operator+(Vector a,Vector b)
{
    return Vector{a.x+b.x,a.y+b.y};
}
Point operator+(Point a,Vector b)
{
    return Point{a.x+b.x,a.y+b.y};
}
Point operator+(Vector a,Point b)
{
    return Point{a.x+b.x,a.y+b.y};
}
int main()
{
    Point a{1,2};    //
    Vector b{3,4};
    auto x = b+b;
    cout<< "b + b = {"<<x.x<<", "<<x.y<<"}"<<endl;
    
    auto y = a+b;
    cout<< "a + b = {"<<y.x<<", "<<y.y<<"}"<<endl;
    
    auto z = b+a;
    cout<< "b + a = {"<<z.x<<", "<<z.y<<"}"<<endl;
    return 0;
}

3.模本类Vector(动态数组)
vector的常见使用方法

vector<类型>对象名(数组长度,元素初值);

vector<int> a(101;//定义了一个大小为10的整型动态数组,初始化全部为1

这种模板类也是用构造函数进行初始化的;

用new申请动态数组:

int *a=new int[n];//动态分配n个整型长度的内存给a,这个数组名就为a
int *a=new int;  //动态分配了一个整型内存,把地址给a,没有初始化
int *a=new int(1);//动态分配了一个整型内存,把地址给a,将这个内存初始化为1
int *a=new int{1};//与上述同样的效果

Line *line;
line = new Line();//动态分配了一个类Line内存,把地址给line,调用这个类的构造函数将这个内存初始化
line = new Line{}//这个与上面是同样的效果,也会调用构造函数初始化

4.用new动态分配

#include <iostream>
#include <string>

using namespace std;
struct point
{
    int x;
    int y;
    //point(int z) : x{z}, y(z){};
};
int main()
{
	auto p = new point[3]{{1,2},{3},{5,6}};
	auto p1 = new point{1,2};
    cout << p[1].y << endl;
    return 0;
}
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值