-
C++ 初始化列表
2020-07-18 19:16:24//初始化列表 class Person{ public: //传统初始化操作 Person(int a, int b, int c) { m_A = a; m_B = b; m_C = c; } int m_A; int m_B; int m_C; }; void test01() { Person p(10,20, 30).#include <iostream> using namespace std; #include <string> //初始化列表 class Person{ public: //传统初始化操作 Person(int a, int b, int c) { m_A = a; m_B = b; m_C = c; } int m_A; int m_B; int m_C; }; void test01() { Person p(10,20, 30); cout << "m_A=" << p.m_A << endl; cout << "m_B=" << p.m_B << endl; cout << "m_C=" << p.m_C << endl; } int main() { test01(); system("pause"); }
#include <iostream> using namespace std; #include <string> //初始化列表 class Person{ public: //传统初始化操作 /*Person(int a, int b, int c) { m_A = a; m_B = b; m_C = c; } */ //初始化列表初始化属性 Person(): m_A(10),m_B(20),m_C(30){} int m_A; int m_B; int m_C; }; void test01() { // Person p(10,20, 30); Person p; cout << "m_A=" << p.m_A << endl; cout << "m_B=" << p.m_B << endl; cout << "m_C=" << p.m_C << endl; } int main() { test01(); system("pause"); }
上面两种方式都正常的输出:
不过我们发现第二种的初始化列表写死了,不够灵活,我们怎么才能灵活的赋值
#include <iostream> using namespace std; #include <string> //初始化列表 class Person{ public: //传统初始化操作 /*Person(int a, int b, int c) { m_A = a; m_B = b; m_C = c; } */ //初始化列表初始化属性 Person(int a, int b, int c): m_A(a),m_B(b),m_C(c){} int m_A; int m_B; int m_C; }; void test01() { // Person p(10,20, 30); Person p(30,50,60); cout << "m_A=" << p.m_A << endl; cout << "m_B=" << p.m_B << endl; cout << "m_C=" << p.m_C << endl; } int main() { test01(); system("pause"); }
这个初始化值就比较灵活了
-
C++ 结构体初始化与赋值
2016-05-30 13:28:571.CC++结构体的初始化今天看到项目中对自定义结构体初始化方式有点陌生,特在此罗列一下可用的结构体初始化的方式。对结构体struct A { int b; int c; }有几种初始化方式:第一种:struct A a = { .b = 1, ...1.结构体初始化
结构体是常用的自定义构造类型,是一种很常见的数据打包方法。结构体对象的初始化有多种方式,分为顺序初始化、指定初始化、构造函数初始化。假如有如下结构体。
struct A { int b; int c; };
(1)顺序初始化因为书写起来较为简约,是我们最常用的初始化方式,但相对于指定初始化,无法变更数据成员初始化顺序,灵活性较差,而且表现形式不直观,不能一眼看出 struct 各个数据成员的值。
A a = {1, 2};
(2)指定初始化(Designated Initializer)实现上有两种方式,一种是通过点号加赋值符号实现,即“.fieldname=value”,另外一种是通过冒号实现,即“fieldname:value”,其中 fieldname 为结构体成员名称 。前者是 C99 标准引入的初始化方式,后者是 GCC 的扩展。遗憾的是有些编译器并不支持指定初始化,比如 Visual C++。
// 点号+赋值符号 A a = {.b = 1, .c = 2}; //冒号 A a = {b:1, c:2};
Linux 内核喜欢用 .fieldname=value 的方式进行初始化,使用指定初始化,一个明显的优点是成员初始化顺序和个数可变,并且扩展性好,比如在结构体非末尾处增加字段时,避免了传统顺序初始化带来的大量修改。
(3)构造函数初始化常见于 C++ 代码中,因为 C++ 中的 struct 可以看作 class,结构体也可以拥有构造函数,所以我们可以通过结构体的构造函数来初始化结构体对象。给定带有构造函数的结构体:
struct A { A(int b,int c) { this->b=b; this->c=c; }; int b; int c; }
那么结构体对象的初始化可以像类对象初始化那样:
A a(1,2);
注意: struct 如果定义了构造函数的话,就不能用大括号进行初始化了,即不能再使用指定初始化与顺序初始化了。
2.结构体赋值
变量的赋值和初始化是不一样的,初始化是在变量定义的时候完成的,是属于变量定义的一部分,赋值是在变量定义完成之后想改变变量值的时候所采取的操作。还是给定结构体 A:
struct A { int b; int c; };
注意: 结构体变量的赋值是不能采用大括号的方式进行赋值的,例如下面的赋值是不允许的。
A a; a={1,2}; // 错误赋值
下面列出常见结构体变量赋值的方法。
(1)使用 memset 对结构体变量进行置空操作:
// 按照编译器默认的方式进行初始化(如果 a 是全局静态存储区的变量,默认初始化为0,如果是栈上的局部变量,默认初始化为随机值) A a; memset(&a,0,sizeof(a));
(2)依次给每一个结构体成员变量进行赋值:
A a; a.b=1; a.c=2;
(3)使用已有的结构体变量给另一个结构体变量赋值。也就是说结构体变量之间是可以相互赋值的。
A a={1,2}; struct A a1; a1=a; // 将已有的结构体变量赋给a1
初始化与赋值有着本质的区别,初始化是变量定义时的第一次赋值,赋值则是定义之后的值的变更操作,概念上不同,所以实现上也不一样。
参考文献
[1] 2016腾讯春季校园实习招聘技术岗初试(一面)问题汇总(CC++后台)
[2] 结构体初始化
[3] C结构体-designated initializer
[4] C语言结构体声明中冒号的使用(占位符) & C结构体的乱序初始化 -
-
c++ 子类构造函数初始化及父类构造初始化
2018-08-30 15:58:50我们知道,构造方法是用来初始化类对象的。如果在类中没有显式地声明构造函数,那么编译器会自动创建一个默认的构造函数;并且这个默认的构造函数仅仅在没有显式地声明构造函数的情况下才会被创建创建。 构造函数...我们知道,构造方法是用来初始化类对象的。如果在类中没有显式地声明构造函数,那么编译器会自动创建一个默认的构造函数;并且这个默认的构造函数仅仅在没有显式地声明构造函数的情况下才会被创建创建。
构造函数与父类的其它成员(成员变量和成员方法)不同,它不能被子类继承。因此,在创建子类对象时,为了初始化从父类中继承来的成员变量,编译器需要调用其父类的构造函数。如果子类的构造函数没有显示地调用父类的构造函数,则默认调用父类的无参构造函数,至于什么事显式调用,在下面会详细说明!关于子类中构造函数的构造原则,总结如下,欢迎大家指导与批评。
1.父类没有声明构造函数
(1)子类也没有声明自己的构造函数,则父类和子类均由编译器生成默认的构造函数。
(2)子类中声明了构造函数(无参或者带参),则子类的构造函数可以写成任何形式,不用顾忌父类的构造函数。在创建子类对象时,先调用父类默认的构造函数(编译器自动生成),再调用子类的构造函数。
2.父类只声明了无参构造函数
如果子类的构造函数没有显式地调用父类的构造,则将会调用父类的无参构造函数。也就是说,父类的无参构造函数将会被隐式地调用。
3.父类只声明了带参构造函数
在这种情况下,要特别注意。因为父类只有带参的构造函数,所以如果子类中的构造函数没有显示地调用父类的带参构造函数,则会报错,所以必需显示地调用。
关于构造函数的显示调用,参见下例。
class animal { protected: //成员变量,声明为protected或者public,这里选择protected int height; //若声明为private,则不能被子类继承访问,会报错 int weight; public: animal(int height,int weight) //带参的构造函数 { this->height=height; this->weight=weight; cout<<"animal的带参构造函数被调用"<<endl; } virtual ~animal() { cout<<"animal的析构函数被调用"<<endl; } }; //子类 class fish:public animal { public: fish():animal(20, 10) //显示调用父类的构造函数 { cout<<"fish的构造函数被调用"<<endl; } virtual ~fish() { cout<<"fish的析构函数被调用"<<endl; } };
在子类fish的构造函数中,加上一个冒号(:),然后加上父类的带参构造函数,这就是父类构造函数的显式调用。这样,在子类的构造函数被调用时,系统就会去调用父类的带参构造函数,从而实现初始化父类的成员变量。运行结果如下:
注意:
如果父类只有带参的构造函数,且该带参的构造函数的参数有默认值,此时在子类中也可以不用显示的调用父类的构造函数。
// 父类的构造函数,改成带有默认值的参数, 这样在子类中就可以不用显示调用了 animal(int height=19 ,int weight=20) //带参的构造函数 { this->height=height; this->weight=weight; cout<<"animal的带参构造函数被调用"<<endl; }
4.父类同时声明了无参和带参构造函数
在这种情况下,子类只需要实现父类的一个构造函数即可,不管是无参的还是带参的构造函数。如果子类的构造函数没有显示地调用父类的构造函数(无参或带参),则默认调用父类的无参构造函数。
//父类 class animal { protected: //成员变量,声明为protected或者public,这里选择protected int height; //若声明为private,则不能被子类继承访问,会报错 int weight; public: animal() { height=0; weight=0; cout<<"animal的无参构造函数被调用"<<endl; } animal(int height,int weight) //带参的构造函数 { this->height=height; this->weight=weight; cout<<"animal的带参构造函数被调用"<<endl; } virtual ~animal() { cout<<"animal的析构函数被调用"<<endl; } }; //子类 class fish:public animal { public: fish() //没有显示地调用父类的构造函数(无参或带参),则默认调用父类的无参构造函数 { cout<<"fish的构造函数被调用"<<endl; } virtual ~fish() { cout<<"fish的析构函数被调用"<<endl; } };
运行结果如下:
总结以上几条,可以归纳出C++中子类继承父类时构造函数的写法的规律:当父类有显式地声明了构造函数时,子类最低限度的实现父类中的一个;当父类没有声明构造函数时,子类可以不声明构造函数或者任意地书写构造函数。
-
权值初始化——高斯初始化,Xavier初始化,MSRA初始化,He初始化
2019-09-11 21:34:44常用的初始化方法有四种,分别是高斯初始化、Xavier初始化和MSRA初始化。它们一般都把偏置初始化为0,但对权值进行随机初始化。其中,高斯初始化比较容易理解,就是根据某个高斯分布来初始化权值,但均值通常选0,...在训练神经网络之前,必须对其全值和偏置进行初始化。常用的初始化方法有四种,分别是高斯初始化、Xavier初始化和MSRA初始化。它们一般都把偏置初始化为0,但对权值进行随机初始化。其中,高斯初始化比较容易理解,就是根据某个高斯分布来初始化权值,但均值通常选0,方差需要按经验人工选择。下面对Xavier和MSRA以及He做进一步的说明。
Xavier的基本思想是保持信息在神经网络中流动过程的方差不变。假设激活函数是关于0点对称的,且主要针对于全连接神经网络,适应于tanh和softsign。这种方法在实际应用时根据一个均匀分布来初始化权值。如果某个神经元
有
个输入
,相应的连接权值为
,则满足关系:
那么采用Xavier进行初始化的方法就是:
MSRA的基本思想与Xavier类似,但主要是针对ReLU和PReLU激活函数来设计的。这种方法在实际应用时根据一个方差为
的零均匀高斯分布来初始化权值,即
He的基本思想是正向传播时,状态值的方差保持不变;反向传播时,关于激活值的梯度的方差保持不变。
适用于ReLU的初始化方法:
适用于Leakly ReLU的初始化方法:
在darknet中CNN的权值初始化采用He的方法,具体实现见源码。后续我们会在【darknet源码解析】系列中详细讲解其实现。
完,
-
【pytorch参数初始化】 pytorch默认参数初始化以及自定义参数初始化
2019-07-30 10:25:41在pytorch中,有自己默认初始化参数方式,所以在你定义好网络结构以后,不进行参数初始化也是可以的。 1.Conv2d继承自_ConvNd,在_ConvNd中,可以看到默认参数就是进行初始化的,如下图所示 2.torch.nn.B... -
C语言中的结构体,结构体中数组初始化与赋值
2018-01-03 10:18:33最近写c语言中的结构体遇到了些问题,从网上找了些资料如下: 结构体是连续存储的,但由于结构体中成员类型各异,所以会存在内存对齐问题,也就是内存里面会有空档,...结构体是可以直接初始化的,在定义的时候,就可 -
vector 的六种 创建和初始化方法
2018-05-22 08:26:39C++的初始化方法很多,各种初始化方法有一些不同。(1): vector<int> ilist1; 默认初始化,vector为空, size为0,表明容器中没有元素,而且 capacity 也返回 0,意味着还没有分配内存空间。这种初始... -
类初始化构造函数初始化类成员时必须使用初始化列表初始化的情况
2018-04-12 00:08:49构造函数初始化时必须采用初始化列表一共有三种情况, 1. 没有默认构造函数的类成员对象() 2. (常量成员)需要初始化const修饰的类成员 3. (引用)需要初始化引用成员数据class A { ... private: int a; }; ... -
数组的三种初始方法 静态初始化 默认初始化 动态初始化
2018-07-31 02:56:41* 测试数组的三种初始化的方式 * @author 高淇 * */ public class Test02 { public static void main(String[] args) { //静态初始化 int[] a = {2,4,65}; User[] b ={ new User(1001,&... -
C++11 就地初始化与列表初始化
2017-02-15 14:12:56C++11之前,C++主要有以下几种初始化方式://小括号初始化 string str(&amp;quot;hello&amp;quot;);//等号初始化 string str=&amp;quot;hello&amp;quot;;//大括号初始化 struct ... -
初始化器初始化dictionary
2015-11-19 14:48:04初始化器 2015年3月29日 9:55 如何用初始化器初始化Dictionary Dictionary<string, int> dic = newDictionary<string, int> { {"name1",3}, {"name2",3}, {... -
深度学习之参数初始化——Xavier初始化
2019-05-30 15:23:16文章目录标准初始化方法形式激活值和梯度特性实验Xavier初始化形式满足Glorot条件的初始化激活值和梯度特性实验Xavier初始化的缺点 Understanding the difficulty of training deep feedforward neural networks by ... -
Xavier初始化和He初始化
2018-11-22 10:03:30Xavier初始化: 条件:正向传播时,激活值的方差保持不变;反向传播时,关于状态值的梯度的方差保持不变。 初始化方法: W∼U[−6ni+ni+1,6ni+ni+1]W\sim U[-\frac{\sqrt6}{\sqrt{n_i+n_{i+1}}},\frac{\sqrt6... -
初始化列表中初始化数组
2019-03-23 14:28:54学习了一下前缀树。 需要用到一个结构体保存两个指针,如下 struct Node ...能不能将初始化操作放在初始化列表中呢,如下 以上两种写法都有问题,突然想到,数组应该用大括号初始化啊 就酱。 ... -
java List的初始化
2017-02-23 14:25:31java List<String>的初始化 -
初始化git的初始化用户信息
2018-05-21 20:38:01初始化用户信息 系统级别初始化用户 用户级别初始用户 项目级别初始化用户 举例验证 在用户级别设定 在项目级别设定 验证配置 官方帮助信息 初始化用户信息 初始化用户信息,当人为提交add或commit编辑... -
深入理解Java对象的创建过程:类的初始化与实例化
2017-05-18 14:17:45在Java中,一个对象在可以被使用之前必须要被正确地初始化,这一点是Java规范规定的。在实例化一个对象时,JVM首先会检查相关类型是否已经加载并初始化,如果没有,则JVM立即进行加载并调用类构造器完成类的初始化。... -
C++中的值初始化和默认初始化
2018-10-31 21:33:081、值初始化 顾名思义,就是用数值初始化变量。如果没有给定一个初始值,就会根据变量或类对象的类型提供一个初始值。对于int类型其值初始化后的值为0。 2、默认初始化:如果定义变量时没有指定初值,则变量被... -
静态初始化和实例初始化
2016-04-23 15:40:07静态初始化块 实例初始化块, -
数组静态初始化和动态初始化的区别
2019-02-26 10:54:02一,java初始化 注意:java数组是静态的,必须经过初始化后才可以使用,一但初始化数组长度,长度是不可以改变的。 1.静态初始化:初始化时由程序猿显示指定每个数组元素的初始值,由系统决定数组的长度 举个栗子: ... -
C/C++初始化和去初始化函数
2018-06-10 16:24:21初始化/去初始化函数根据作用域可以分为几种不同的应用情形 1. 全局初始化/去初始化 这一次运行程序只做这一次初始化/去初始化 2. 模块初始化/去初始化 每次加载/卸载这个模块都调用一次初始化/去初始化 ... -
C++使用初始化列表初始化数据成员的三种情况
2018-08-11 15:04:271.分配内存,调用构造函数时,隐式/显示的初始化各数据成员(构造函数列表的初始化方式不是按照列表的的顺序,而是按照变量声明的顺序同时初始化显隐数据成员); 2.进入构造函数后在构造函数中执行一般赋值与计算。... -
值初始化和默认初始化的区别
2018-03-11 20:29:08参考资料[1]P185指出,如果局部变量没有显式的初始化值,它将执行值初始化(不是默认初始化!),内置类型的局部静态变量初始化为0 1 背景 参考资料[1]P39提到,在C++语言中,初始化与赋值并不是同一个概念:... -
Java中的静态初始化和非静态初始化
2017-01-09 19:03:30Java中的静态初始化和非静态初始化 -
Java对象数组的静态初始化和动态初始化
2018-04-02 17:06:16和基本数据类型一样,对象数组初始化也分为静态初始化,动态初始化两种 对象数组动态初始化 //定义Person类 class Person { public int age; } //主类 public class Test { public static void main(String[] ... -
接口初始化和类初始化区别
2017-11-09 20:59:10虚拟机规范严格规定了有且只有四种情况必须立即对类进行初始化: 1. 遇到new、getstatic、putstatic、invokestatic这四条字节码指令时, 如果类还没有进行过初始化,则需要先触发其初始化。 生成这四条指令最常见...
-
第六章 Caché 变量大全 $HOROLOG 变量
-
实验1认识Packer Tracer软件.pkt
-
9000题库-上.iso
-
第12章 图像轮廓 -- 绘制图像轮廓 cv2.drawContours()
-
21年新接口自动化测试视频postman教程 零基础接口测试
-
Centos安装PHP7及配置php-fpm开机启动
-
【数据分析-随到随学】Hadoop数据分析
-
mfd是什么格式文件
-
【Leetcode】1496. Path Crossing
-
微电子电路实验仿真代码
-
数据结构算法实现(严蔚敏版配套实现程序)
-
阿里巴巴开发手册-最新版.pdf
-
html个人简历表格制作
-
python办公自动化技巧
-
警灯,警铃四合一【Arduino玩具】
-
Java学习路线,好的学习路线和好的方法,能让我们少走些弯路
-
php笔记
-
《马克思主义基本原理》考试大纲_Touale的博客-CSDN博客.pdf
-
HTML调用PHP的方法
-
转行做IT-第1章 计算机基础