-
2018-05-18 18:15:04
目录:
定义
与其他函数不同,构造函数除了有名字,参数列表和函数体之外,还可以有初始化列表,初始化列表以冒号开头,后跟一系列以逗号分隔的初始化字段。
class foo { public: foo(string s, int i):name(s), id(i){} ; // 初始化列表 private: string name ;int id ; };
从概念上来讲,构造函数的执行可以分成两个阶段,初始化阶段和计算阶段,初始化阶段先于计算阶段.
初始化阶段
所有类类型(class type)的成员都会在初始化阶段初始化,即使该成员没有出现在构造函数的初始化列表中.计算阶段
一般用于执行构造函数体内的赋值操作。下面的代码中,其中Test1有构造函数,拷贝构造函数及赋值运算符,为的是方便查看结果,Test2是个测试类,它以Test1的对象为成员,我们看一下Test2的构造函数是怎么样执行的。
class Test1 { public: Test1() // 无参构造函数 {cout << "Construct Test1" << endl ;} Test1(const Test1& t1) // 拷贝构造函数 {cout << "Copy constructor for Test1" << endl ;this->a = t1.a ;} Test1& operator = (const Test1& t1) // 赋值运算符 {cout << "assignment for Test1" << endl ;this->a = t1.a ;return *this;} int a ; }; class Test2 { public: Test1 test1 ; Test2(Test1 &t1) {test1 = t1 ;} };
调用代码:
Test1 t1 ;
Test2 t2(t1) ;
输出:
Construct Test1
Construct Test1
assignment for Test1解释一下:
第一行输出对应调用代码中第一行,构造一个Test1对象
第二行输出对应Test2构造函数中的代码,用默认的构造函数初始化对象test1 // 这就是所谓的初始化阶段
第三行输出对应Test2的赋值运算符,对test1执行赋值操作 // 这就是所谓的计算阶段使用初始化列表的原因
初始化类的成员有两种方式,一是使用初始化列表,二是在构造函数体内进行赋值操作。
主要是性能问题,对于内置类型,如int, float等,使用初始化类表和在构造函数体内初始化差别不是很大,但是对于类类型来说,最好使用初始化列表,为什么呢?由下面的测试可知,使用初始化列表少了一次调用默认构造函数的过程,这对于数据密集型的类来说,是非常高效的。同样看上面的例子,我们使用初始化列表来实现Test2的构造函数。class Test2 { public: Test1 test1 ; Test2(Test1 &t1):test1(t1){} }
使用同样的调用代码,输出结果如下:
Construct Test1
Copy constructor for Test1第一行输出对应 调用代码的第一行
第二行输出对应Test2的初始化列表,直接调用拷贝构造函数初始化test1,省去了调用默认构造函数的过程。
所以一个好的原则是,能使用初始化列表的时候尽量使用初始化列表.必须使用初始化列表的时候
除了性能问题之外,有些时候合初始化列表是不可或缺的,以下几种情况时必须使用初始化列表
1.常量成员,因为常量只能初始化不能赋值,所以必须放在初始化列表里面
2.引用类型,引用必须在定义的时候初始化,并且不能重新赋值,所以也要写在初始化列表里面
3. 没有默认构造函数的类类型,因为使用初始化列表可以不必调用默认构造函数来初始化,而是直接调用拷贝构造函数初始化class Test1 { public: Test1(int a):i(a){} int i; }; class Test2 { public: Test1 test1 ; Test2(Test1 &t1) {test1 = t1 ;} };
以上代码无法通过编译,因为Test2的构造函数中test1 = t1这一行实际上分成两步执行:
1. 调用Test1的默认构造函数来初始化test1
由于Test1没有默认的构造函数,所以1 无法执行,故而编译错误。正确的代码如下,使用初始化列表代替赋值操作class Test2 { public: Test1 test1 ; Test2(int x):test1(x){} }
成员变量的顺序
成员是按照他们在类中出现的顺序进行初始化的,而不是按照他们在初始化列表出现的顺序初始化的,看代码:
class foo { public: int i ;int j ; foo(int x):i(x), j(i){}; // ok, 先初始化i,后初始化j };
再看下面的代码:
class foo { public: int i ;int j ; foo(int x):j(x), i(j){} // i值未定义 };
这里i的值是未定义的因为虽然j在初始化列表里面出现在i前面,但是i先于j定义,所以先初始化i,而i由j初始化,此时j尚未初始化,所以导致i的值未定义。一个好的习惯是,按照成员定义的顺序进行初始化。
更多相关内容 -
C++类和对象(下)——初始化列表、static成员和友元
2021-03-08 09:23:18C++类和对象——初始化列表、static成员和友元一、再谈构造函数1.1 构造函数整体赋值1.2 初始化列表三级目录 关于C++类和对象的学习 C++类和对象(上)——类的基本概念、类的限定符及封装和类成员函数的this指针 C++...C++类和对象——初始化列表、static成员和友元
关于C++类和对象的学习
C++类和对象(上)——类的基本概念、类的限定符及封装和类成员函数的this指针
C++类和对象(中)——类的6个默认成员函数(构造、析构、拷贝构造、赋值运算符重载)
一、再谈构造函数
1.1 构造函数整体赋值
在创建对象时,编译器通过调用构造函数,给对象中各个成员变量一个合适的初始值。例如我们之前创建的Date类
class Date { public: Date(int year = 1900, int month = 1, int day = 1) { _year = year; _month = month; _day = day; } private: int _year; int _month; int _day; };
虽然上述构造函数调用之后,对象中已经有了一个初始值,但是不能将其称作为类对象成员的初始化,构造函数体中的语句只能将其称作为赋初值,而不能称作初始化。因为初始化只能初始化一次,而构造函数体内可以多次赋值。
1.2 初始化列表
<1>为什么有初始化列表?
对于我们定义的日期类,当类中出现以下成员时,如果只用构造函数则无法完成变量的初始化了,以下的成员变量需要在定义的时候就需要初始化
- 引用成员变量
- const成员变量
- 自定义类型的成员变量
其次对于自定义的类成员变量,不使用初始化列表会调用多次构造函数
<2> 如何使用初始化列表
初始化列表:以一个冒号开始,接着是一个以逗号分隔的数据成员列表,每个"成员变量"后面跟一个放在括号中的初始值或表达式。
注意:每个成员变量在初始化列表中只能出现一次//1.2.2 class Time { public: Time(int hour = 1, int minute=1,int second = 1) :_hour(hour) ,_minute(minute) ,_second(second) { cout << "Time(int hour = 1, int minute=1,int second = 1)" << endl; } private: int _hour; int _minute; int _second; }; class Date { public: //初始化列表写法 Date(int year=1900, int month=1, int day=1,int hour=1,int minute=1,int second=1) :_year(year) ,_month(month) ,_day(day) ,_n(10) ,_ref(day) ,_t(hour,minute,second) { cout << "Date(int year, int month, int day,int hour,int minute,int second)" << endl; } private: int _year; int _month; int _day; //定义的时候需要初始化 int& _ref; //引用 const int _n; //const成员变量 Time _t; //自定义类型的成员变量 }; void Test2() { Date d1(2021,3,9,2,2,2); }
结果
<3> 成员变量在类中声明次序就是其在初始化列表中的初始化顺序,与其在初始化列表中的先后次序无关
如下代码的运行结果是什么?
//1.2.3 class A { public: A(int a) :_a1(a) , _a2(_a1) {} void Print() { cout << _a1 << " " << _a2 << endl; } private: int _a2; int _a1; }; void Test2() { A aa(1); aa.Print(); }
结果
1.3 explicit关键字
<1> 匿名对象
匿名对象顾名思义就是没有名字,其作用域只在一行中有效,例如下面的代码
//1.3.1 class B { public: B(int b = 0) :_b(b) { cout << "B(int b = 0)" << endl; } //析构函数 ~B() { cout << "~B()" << endl; } private: int _b; }; int main() { B bb(10); //生命周期在main函数域 B(2); //匿名对象生命周期在这一行 return 0; }
<2> 为什么有explicit关键字?
对于c++来说,构造函数不仅可以构造与初始化对象,对于单个参数的构造函数,还具有类型转换的作用。
当我们定义一个类进行初始化时,如果我们采取下面这种定义方式,编译器会自动生成一个匿名对象,然后用匿名对象对cc对象进行拷贝构造。
//1.3.2 class C { public: C(int c) :_c(c) { cout << "C()" << endl; } private: int _c; }; int main() { C cc(2); cc = 8; //编译器会自动生成一个匿名对象,然后用匿名对象对cc对象进行拷贝构造 return 0; }
<3> 如何使用explicit关键字?
用explicit修饰构造函数,将会禁止单参构造函数的隐式转换。
//1.3.3 class C { public: explicit C(int c) :_c(c) { cout << "explicit C(int c)" << endl; } private: int _c; }; int main() { C cc(2); cc = 8; //编译器会自动生成一个匿名对象,然后用匿名对象对cc对象进行拷贝构造 return 0; }
二、static成员
2.1 概念
声明为static的类成员称为类的静态成员,用static修饰的成员变量,称之为静态成员变量;用static修饰的成员函数,称之为静态成员函数。静态的成员变量一定要在类外进行初始化。
面试题:实现一个类,计算程序中创建出了多少个类对象?这个时候我们就可以使用static成员变量和static成员函数来实现
//2.1 实现一个类,计算程序中创建出了多少个类对象。 class A { public: //构造函数 A() { ++_scount; } //拷贝构造函数 A(const A& a) { ++_scount; } static int GetAcount() { return _scount; } private: static int _scount; }; //初始化在类外 int A::_scount = 0; void TestA() { cout << A::GetAcount() << endl; A aa; A bb; A cc(bb); cout << A::GetAcount() << endl; }
2.2 特性
<1> 静态成员为所有类对象所共享,不属于某个具体的实例
<2> 静态成员变量必须在类外定义,定义时不添加static关键字
<3> 类静态成员即可用类名::静态成员或者对象.静态成员来访问
<4> 静态成员函数没有隐藏的this指针,不能访问任何非静态成员
<5>静态成员和类的普通成员一样,也有public、protected、private3种访问级别,也可以具有返回值
Q1: 静态成员函数可以调用非静态成员函数吗?
不可以,因为静态成员函数没有隐藏的this指针
Q2:非静态成员函数可以调用类的静态成员函数吗?
可以,因为非静态成员函数含有this指针,指定了静态成员函数的类域
三、C++11的成员初始化新玩法
3.1 为什么?
对于C++98而言,类内自定义的内置类型,编译器会进行初始化,而其他内置类型不会,因此出现则会中初始化方法。
具体查看这篇博客的2.2.7节内容
C++类和对象(中)——类的6个默认成员函数(构造、析构、拷贝构造、赋值运算符重载)
3.2 怎么用?
C++11支持非静态成员变量在声明时进行初始化赋值,但是要注意这里不是初始化,这里是给声明的成员变量缺省值。
//3.C++11的成员初始化新玩法 class B { public: B(int b = 0) :_b(b) {} int _b; }; class A { public: void Print() { cout << a << endl; cout << b._b << endl; cout << p << endl; } private: // 非静态成员变量,可以在成员声明时给缺省值。 int a = 10; B b = 20; int* p = (int*)malloc(4); //静态成员不可以 static int n; }; int A::n = 10; int main() { A a; a.Print(); return 0; }
四、友元
- 友元分为:友元函数和友元类
- 友元提供了一种突破封装的方式,有时提供了便利。但是友元会增加耦合度,破坏了封装,所以友元不宜多用
4.1 友元函数
问题:现在我们尝试去重载operator<<,然后发现我们没办法将operator<<重载成成员函数。因为cout的输出流对象和隐含的this指针在抢占第一个参数的位置。this指针默认是第一个参数也就是左操作数了。但是实际使用中cout需要是第一个形参对象,才能正常使用。所以我们要将operator<<重载成全局函数。但是这样的话,又会导致类外没办法访问成员,那么这里就需要友元来解决。operator>>同理
//4.1 class Date { public: Date(int year, int month, int day) : _year(year) , _month(month) , _day(day) {} ostream& operator<<(ostream& _cout) { _cout << _year << "-" << _month << "-" << _day; return _cout; } private: int _year; int _month; int _day; }; int main() { Date d(2017, 12, 24); d << cout; return 0; }
友元函数可以直接访问类的私有成员,它是定义在类外部的普通函数,不属于任何类,但需要在类的内部声明,声明时需要加friend关键字。//4.1 class Date { friend ostream& operator<<(ostream& _cout, const Date& d); friend istream& operator >> (istream& _cin, Date& d); public: Date(int year, int month, int day) : _year(year) , _month(month) , _day(day) {} ostream& operator<<(ostream& _cout) { _cout << _year << "-" << _month << "-" << _day; return _cout; } private: int _year; int _month; int _day; }; ostream& operator<<(ostream& _cout, const Date& d) { _cout << d._year << "-" << d._month << "-" << d._day << endl; return _cout; } istream& operator >> (istream& _cin, Date& d) { _cin >> d._year >> d._month >> d._day; return _cin; } int main() { Date d(2017, 12, 24); cout<<d; //Date d1; cin >> d; cout << d; return 0; }
4.2 友元类
友元类的所有成员函数都可以是另一个类的友元函数,都可以访问另一个类中的非公有成员。
- 友元关系是单向的,不具有交换性。
比如下面Time类和Date类,在Time类中声明Date类为其友元类,那么可以在Date类中直接访问Time类的私有成员变量,但想在Time类中访问Date类中私有的成员变量则不行。 - 友元关系不能传递
如果B是A的友元,C是B的友元,则不能说明C时A的友元。
class Date; // 前置声明 class Time { friend class Date; // 声明日期类为时间类的友元类,则在日期类中就直接访问Time类中的私有成员变量 public: Time(int hour=0, int minute=0, int second=0) : _hour(hour) , _minute(minute) , _second(second) {} private: int _hour; int _minute; int _second; }; class Date { public: Date(int year = 1900, int month = 1, int day = 1) : _year(year) , _month(month) , _day(day) {} void SetTimeOfDate(int hour, int minute, int second) { // 直接访问时间类私有的成员变量 _t._hour = hour; _t._minute = minute; _t._second = second; } private: int _year; int _month; int _day; Time _t; };
五、内部类
概念:如果一个类定义在另一个类的内部,这个内部类就叫做内部类。注意此时这个内部类是一个独立的类,它不属于外部类,更不能通过外部类的对象去调用内部类。外部类对内部类没有任何优越的访问权限。
注意:内部类就是外部类的友元类。注意友元类的定义,内部类可以通过外部类的对象参数来访问外部类中的所有成员。但是外部类不是内部类的友元。
特性:
- 内部类可以定义在外部类的public、protected、private都是可以的。
- 注意内部类可以直接访问外部类中的static、枚举成员,不需要外部类的对象/类名。
- sizeof(外部类)=外部类,和内部类没有任何关系
class A { private: static int k; int h; public: class B { public: void foo(const A& a) { cout << k << endl;//OK cout << a.h << endl;//OK } }; }; int A::k = 1; int main() { A::B b; b.foo(A()); return 0; }
-
Python如何初始化列表?
2020-12-16 01:25:05Python是一种非常灵活的语言,可以通过多种方式执行单个任务,例如,可以通过多种方式执行初始化列表。下面本篇文章就来带大家了解几种Python初始化的方法,并比较一下这几种方法的效率,希望对大家有所帮助。下面...Python是一种非常灵活的语言,可以通过多种方式执行单个任务,例如,可以通过多种方式执行初始化列表。下面本篇文章就来带大家了解几种Python初始化的方法,并比较一下这几种方法的效率,希望对大家有所帮助。
下面我们就来介绍在Python中初始化列表(我们创建大小为1000并使用零初始化的列表)的一些方法。
方法一:使用for循环和append()
我们可以创建一个空的列表,并使用append()方法通过for循环n次来将元素添加到列表中。arr = []
for i in range(1000):
arr.append(0)
方法二:使用带计数器变量的while循环和append()
这和方法一有点类似,但是我们使用while循环代替for循环。arr = []
i = 0
while(i<1000):
arr.append(0)
方法三:使用列表推导(List Comprehension)
列表推导(List Comprehension) 是一种数学家用来实现众所周知标记集合的Python方式。它由方括号组成,包含一个表达式,后跟一个for子句,后面跟一个可选的if子句。
表达式可以是我们想要放入列表中的任何类型的对象;由于我们用零初始化列表,因此我们的表达式将只为0。arr = [0 for i in range(1000)]
说明:用列表推导可以编写高效率的代码,它的执行速度比for循环快35%。
方法四:使用*运算符
运算符可以用作[object] * n,其中n是数组中元素的数目。arr = [0]*1000
代码执行时间比较
下面我们来看看这四种方法的执行时间,看看那种方法更快。
示例:我们将计算每种方法在500次上初始化10000个元素的数组所花费的平均时间。# 导入时间模块以计算时间
import time
# 初始化列表以保存时间
forLoopTime = []
whileLoopTime = []
listComprehensionTime = []
starOperatorTime = []
# 重复此过程500次,并计算所用的平均时间。
for k in range(500):
# 开始时间
start = time.time()
# 声明空列表
a = []
# 执行for循环10000次
for i in range(10000):
a.append(0)
# 停止时间
stop = time.time()
forLoopTime.append(stop-start)
# 开始时间
start = time.time()
# 声明空列表
a = []
i = 0
# 执行while循环10000次
while(i<10000):
a.append(0)
i+= 1
stop = time.time()
whileLoopTime.append(stop-start)
start = time.time()
# 使用列表推导(List Comprehension) 来初始化列表
a = [0 for i in range(10000)]
stop = time.time()
listComprehensionTime.append(stop-start)
start = time.time()
# 使用*运算符
a = [0]*10000
stop = time.time()
starOperatorTime.append(stop-start)
print("for循环所用的平均时间:" + str(sum(forLoopTime)/100))
print("while循环所用的平均时间:" + str(sum(whileLoopTime)/100))
print("列表推导所用的平均时间:" + str(sum(listComprehensionTime)/100))
print("* 运算符所用的平均时间: " + str(sum(starOperatorTime)/100))
输出:
注意:时间将根据执行此代码的平台而有所不同。这些时间仅用于研究这些初始化方法的相对性能。
● 可以看出,for和while循环所用时间几乎相同。
● 列表推导的性能比for和while循环要好得多,前者的速度要快3-5倍。当我们尝试创建1-1000的数字列表时,可以看到另一个这种差异的例子。使用列表推导比使用append()要好得多。a = [i for i in range(1,1001)]
● 使用*运算符比其余方法更快,这是您应该初始化列表的方式
相关视频教程推荐:《Python教程》
-
Python初始化列表
2019-04-29 18:17:49Python初始化列表 下面我们就来介绍在Python中初始化列表(我们创建大小为1000并使用零初始化的列表)的一些方法。 1)方法一:使用for循环和append()函数 arr = [] for i in range(1000): arr.append(0) 2)方法...Python初始化列表
下面我们就来介绍在Python中初始化列表(我们创建大小为1000并使用零初始化的列表)的一些方法。
1)方法一:使用for循环和append()函数
arr = [] for i in range(1000): arr.append(0)
2)方法二:使用带计数器变量的while循环和append()
arr = [] i = 0 while(i<1000): arr.append(0)
3)方法三:使用列表推导(List Comprehension)
列表推导(List Comprehension) 是一种数学家用来实现众所周知标记集合的Python方式。它由方括号组成,包含一个表达式,后跟一个for子句,后面跟一个可选的if子句。
表达式可以是我们想要放入列表中的任何类型的对象;由于我们用零初始化列表,因此我们的表达式将只为0。
arr = [0 for i in range(1000)]
4)方法四:使用*运算符
运算符可以用作[object] * n,其中n是数组中元素的数目。
arr = [0]*1000
代码执行时间比较
下面我们来看看这四种方法的执行时间,看看那种方法更快。
示例:我们将计算每种方法在500次上初始化10000个元素的数组所花费的平均时间。
# 导入时间模块以计算时间 import time # 初始化列表以保存时间 forLoopTime = [] whileLoopTime = [] listComprehensionTime = [] starOperatorTime = [] # 重复此过程500次,并计算所用的平均时间。 for k in range(500): # 开始时间 start = time.time() # 声明空列表 a = [] # 执行for循环10000次 for i in range(10000): a.append(0) # 停止时间 stop = time.time() forLoopTime.append(stop-start) # 开始时间 start = time.time() # 声明空列表 a = [] i = 0 # 执行while循环10000次 while(i<10000): a.append(0) i+= 1 stop = time.time() whileLoopTime.append(stop-start) # 开始时间 start = time.time() # 使用列表推导(List Comprehension) 来初始化列表 a = [0 for i in range(10000)] stop = time.time() listComprehensionTime.append(stop-start) # 开始时间 start = time.time() # 使用*运算符 a = [0]*10000 stop = time.time() starOperatorTime.append(stop-start) print("for循环所用的平均时间:" + str(sum(forLoopTime)/100)) print("while循环所用的平均时间:" + str(sum(whileLoopTime)/100)) print("列表推导所用的平均时间:" + str(sum(listComprehensionTime)/100)) print("* 运算符所用的平均时间: " + str(sum(starOperatorTime)/100))
输出结果
for循环所用的平均时间:0.008704814910888672 while循环所用的平均时间:0.0133302903175354 列表推导所用的平均时间:0.003199863433837891 * 运算符所用的平均时间: 0.00023694276809692382
注意:时间将根据执行此代码的平台而有所不同。这些时间仅用于研究这些初始化方法的相对性能。
● 可以看出,for和while循环所用时间几乎相同。
● 列表推导的性能比for和while循环要好得多,前者的速度要快3-5倍。当我们尝试创建1-1000的数字列表时,可以看到另一个这种差异的例子。使用列表推导比使用append()要好得多。
`a = [i ``for` `i in range(1,1001)]`
● 使用*运算符比其余方法更快,这是您应该初始化列表的方式
-
必须使用【初始化列表】初始化数据成员的情况
2018-01-29 22:31:17类对象的构造顺序是这样的: 1.分配内存,调用构造函数时,隐式/显示的初始化各数据... 情况一、需要初始化的数据成员是对象的情况(这里包含了继承情况下,通过显示调用父类的构造函数对父类数据成员进行初始化); -
C++中类初始值列表与类内初始化
2020-09-22 12:18:56类的构造函数的作用是对其成员进行初始化。而在构造函数中可以使用初始值列表为新创建的对象的成员进行赋值。 1 初始值列表 在类的构造函数名之后紧跟着冒号,冒号后面是要初始化的成员名,之后是圆括号或者花括号... -
【C++】构造函数初始化列表中成员变量必须初始化的几种情况
2019-03-20 17:10:57有一个类A,其数据成员如下: class A { ... private: int a; public: const int b;...则构造函数中,成员变量一定要通过初始化列表来初始化的是...构造函数中,成员变量一定要通过初始化列表来初始化的有以下几种... -
C++中为什么建议使用初始化列表
2018-07-05 21:59:56什么是初始化列表,来看下面代码,我们有一个日期类对象 我们可以这样来定义构造函数: class Date ... -
类和对象的初始化
2018-06-03 17:26:29本文主要通过例子来理解 Java 中类和对象的初始化顺序问题 -
C++构造函数的初始化列表
2018-12-05 17:30:41构造函数的初始化列表 当一个类的成员变量是另一个类的对象时 例: #include<iostream> using namespace std; class A{ public: A() { cout<<"A()"<<endl;... -
C++必须使用【初始化列表】初始化数据成员的三种情况
2016-12-15 15:13:18类对象的构造顺序是这样的: 1.分配内存,调用构造函数时,隐式/显示的初始化各数据... 情况一、需要初始化的数据成员是对象的情况(这里包含了继承情况下,通过显示调用父类的构造函数对父类数据成员进行初始化); -
C++内嵌对象,初始化列表和默认构造函数详解
2020-05-13 10:11:52由此就引出了初始化列表,默认构造函数的概念与意义 下面我们用一个统一的例子分别介绍这两个概念 #include <iostream> #include <typeinfo> #include <array> using namespace std; class Circle... -
javaSE学习(2):理解一个对象的初始化过程(显示初始化,默认初始化,
2019-05-18 16:15:11/* 以手机类为例,来理解一个内存的...答:默认初始化是系统在堆内存创建一个新的对象时,进行的默认初始化,如null 和0 显示初始化是在类定义时,直接在各个成员变量的定义时,优先进行赋值,这叫显示初始化。 -
C++成员初始化列表
2018-12-16 14:20:38C++类成员初始化列表C++类型定义C++构造函数的初始化列表定义C++构造函数执行的两个阶段为什么使用初始化列表C++里面哪些东西必须放在初始化列表里面成员变量的初始化顺序 这边文章主要学习C++里面的成员初始化列表... -
对象数组的初始化
2018-05-05 11:28:56在建立数组时,可以在定义数组时提供实参以实现初始化。1、如果构造函数只有一个参数,可以直接在等号后面的花括号内提供实参,如: Student stu【3】={10,20,30};2、如果构造函数有多个参数,在定义时在花括号中... -
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 ... -
C++中默认构造函数和构造函数初始化列表
2018-12-13 10:59:45(1)构造函数:C++用于构建类的新对象时需要调用的函数,该函数无返回类型!(注意:是“无”! 不是空!(void))。 (2)默认构造函数:默认构造函数是在调用时不需要显示地传入实参的构造函数。 一个类如果自己... -
成员初始化列表
2017-03-18 17:44:292、成员初始经列表由逗号分隔的初始化列表组成(前面带冒号)。它位于参数列表的右括号之后、函数体左括号之前。 3、初值可以是常量或构造函数的参数列表中的参数。这种方法并不限于初始化常量。 例如下代码: Queue:... -
java对象初始化值的三种方式
2019-07-07 17:17:37第一种:使用xml 张三"/> ...@ConfigurationProperties(prefix= "person") 会在yaml中,找到person定义的key,将里面的...注意点,无论使用哪种方式,对实体类进行值的初始化,对象的字段要set方式,才能赋值 -
c++结构体的两种初始化方法---初始化列表/构造函数
2020-04-12 16:45:40当定义结构体变量时,可以通过两种方式初始化它:使用初始化列表或构造函数。 -
构造函数的初始化列表
2020-02-27 14:22:40需要初始化的数据成员是对象的情况; 需要初始化const修饰的类成员; 需要初始化引用成员数据; 引用类型的成员变量必须在构造函数的初始化列表中进行初始化。对于类成员是const修饰,或是引用类型的情况,是不... -
必须在构造函数初始化列表里进行初始化的数据成员有哪些
2017-05-12 16:06:05一,必须在构造函数初始化列表里进行初始化的数据成员有哪些? 下面是一个自定义的Student类 class Address{}; class Student{ private: const int grade; string &name; Address addr; public: Student(int ... -
JS初始化对象
2020-05-14 18:11:37什么是初始化对象? 顾名思义,我们创建对象时便已调用默认编写的init方法,实现初始化。 我们要求调用say方法时,能输出init里的属性。 实现 一、 先调用init方法 输出: wc 1 这种方法每次需要手动输入,不满足... -
常见对象初始化创建的几种方法
2018-06-26 16:40:47public class UserInfo { public int ID { get; set; } public string UserName { get; set; } public string Password { get; set; } }假设现在有 UserInfo 对象... -
C++ 类(构造函数的成员初始化列表)
2018-07-21 13:29:52构造函数的成员初始化列表 构造函数的成员初始化列表 下面的代码分析了什么时候使用成员初始化列表: class A { private: int a; public: A(int a) { this->a = a; } int getA() { re... -
c++ 必须使用构造函数初始化列表初始化的情况
2018-04-04 09:04:01类对象的构造顺序是这样的: ...使用初始化列表有两个原因: 原因1.必须这样做: 《C++ Primer》中提到在以下三种情况下需要使用初始化成员列表: 情况一、需要初始化的数据成员是对象... -
对象的创建和初始化
2020-12-26 12:28:05文章目录前言一、类和对象的关系二、如何创建和初始化对象1.使用new关键字创建对象2.对象初始化三、构造器 前言 本文主要讲解类和对象的关系,以及如何创建和初始化对象,对构造器的详解 一、类和对象的关系 类... -
C++中的string对象(1)——string对象的初始化
2018-08-13 14:31:131、标准库类型string表示可变长的字符序列,使用时...3、如何初始化类的对象是由类本身决定的,一个类可以定义很多种初始化对象的方式,只不过这些方式之间必须有所区别:或者是初始值的数量不同,或者是类型不同。... -
子类初始化列表不能初始化父类元素 -- class 'Derived' does not have any field named 'x'
2019-12-12 19:14:16缘由 偶尔编写如下代码,编译出错, class ...个人倾向于编译行为,不能再子类的初始化列表显示的父类的成员变量进行初始化;如果需要,在初始化列表中包含父类的相应构造方法(含有初始化列表)。 -
构造函数与初始化列表
2018-08-01 18:17:331)初始化:一个变量或者一个对象在产生的时候就赋予一个值,属于伴随性质 2)赋值:在一个变量或者一个对象在产生之后的任意时刻赋予一个值,属于任意性质 宏观代码上: 1)两者作用相同 2)对于数组和结构体来...