初始化函数列表和构造函数内赋值之区别
既然构造函数初始化列表和构造函数体内赋值都可以对成员变量赋值,那么二者有何区别,是不是二者等效呢?
一、若类的数据成员是静态的(const)和引用类型,必需用初始化列表
静态(const)的数据成员只能初始化而不能赋值,同样引用类型也是只可以被初始化,那么只有用初始化列表。
如:
#include <iostream>
#include <string>
using namespace std;
template<class t>
class namedptr {
public:
namedptr(const string& initname, t *initptr);
private:
const string name; //静态数据成员的初始化必需用初始化列表
t * const ptr;
};
template<class t>
namedptr<t>::namedptr(const string& initname, t *initptr )
: name(initname), ptr(initptr)
{}
//第二种方法是在构造函数体内赋值:
//template<class t>
//namedptr<t>::namedptr(const string& initname, t *initptr)
//{
// name = initname;
// ptr = initptr;
//}
int main()
{
int a = 10;
namedptr<int> Test("SHENZHEN",&a);
}
由于 const string name; //静态数据成员的初始化必需用初始化列表
t * const ptr;
是静态的,如果用构造函数体内赋值,编译会出错。
二、构造函数体内赋值会带来额外的开销,效率会低于构造函数初始化列表
上面的例子改一改:
template<class t>
class namedptr {
public:
namedptr(const string& initname, t *initptr);
private:
string name; //静态数据成员的初始化必需用初始化列表
t * ptr;
};
并且用这两中初始化方法做对比:
//第一种方法:初始化列表
template<class t>
namedptr<t>::namedptr(const string& initname, t *initptr )
: name(initname), ptr(initptr)
{}
//第二种方法是在构造函数体内赋值:
template<class t>
namedptr<t>::namedptr(const string& initname, t *initptr)
{
name = initname;
ptr = initptr;
}
当用第二种方法初始化数据成员时会两次对string的成员函数的调用:一次是缺省构造函数,另一次是赋值。
而用第一种方法(初始化列表)只是一次调用缺省的构造函数,并不会调用赋值函数。会减少不必要的开支,当类相当复杂时,就会看出使用初始化列表的好处。
分享到:
相关推荐
不同之处在于,使用构造函数初始化列表的版本初始化数据成员,没有定义初始化列表的构造函数版本在构造函数体中对数据成员赋值。 请问这里的初始化数据成员与对数据成员赋值的含义是什么?有什么区别? 我知道在数据...
声明、初始化与赋值的区别: 声明:int a; 初始化:int a = 2;(在声明的时候顺带赋值叫做初始化) 赋值:a = 2; 只有定义(int a;)才分配存储空间,初始化必须要有存储空间来初始化 全局变量在声明时候顺带赋值...
讲解了为什么要初始化列表,初始化列表和在构造函数中赋值的区别
构造函数初始化列表以一个冒号开始,接着是以逗号分隔的数据成员列表,每个数据成员后面跟一个放在括号中的初始化式。例如: class CExample { public: int a; float b; //构造函数初始化列表 CExample(): a(0...
C++ 类对像构造时,需要对类成员变量完成初始化赋值操作。...第三行是初始化列表构造 b1 时调用的复制构造函数。第四行调用了一次默认构造函数……第四行是哪儿来的? 这里需要陈述一下“复制构造函数”和
原因:C++可以定义引用类型的成员变量,引用类型的成员变量必须在构造函数的初始化列表中进行初始化。对于类成员是const修饰,或是引用类型的情况,是不允许赋值操作的,(显然嘛,const就是防止被错误赋值的,引用...
它本身是一个类或者是一个结构,而且这个成员它只有一个带参数的构造函数,而没有默认构造函数,这时要对这个类成员进行初始化,就必须调用这个类成员的带参数的构造函数,如果没有初始化列表,那么他将无法完成第一...
3、指定数量和元素值的构造函数 4、指定数量的构造函数 5、拷贝构造函数 二、vector的初始化-赋值 1、.assign(beg, end) 赋值操作 2、.assign(n, elem) 赋值操作 3、重载等号操作符 operator= 4、直接列表初始化 `...
继承和动态内存分配 ...对于构造函数,这是通过在初始化成员列表中调用基类的复制构造函数来完成的,如果不这样做,将自动调用基类的默认构造函数,对于赋值运算符,这是通过使用域解析运算符显示地调用基
关于构造函数的问题,本文是关于构造函数的专题,集中介绍了默认构造函数,初始化列表,重点介绍了复制构造函数, 直接初始化,复制初始化,赋值,临时对象之间的关系,本文内容全面,简单易懂。 本文内容完全属于...
与其他函数不同,构造函数除了有名字,参数列表和函数体之外,还可以有初始化列表,初始化列表以冒号开头,后跟一系列以逗号分隔的初始化字段。在C++中,struct和class的唯一区别是默认的访问性不同,而这里我们不...
前言:最近使用bootstrap组件的时候发现一个易用性问题,很多简单的组件初始化都需要在JS里面写很多的初始化代码,比如一个简单的select标签,因为仅仅只是需要从后台获取数据填充到option里面,可是从后台取数据就...
考虑一下效率的可以再构造函数的初始化列表中进行。 class CA { public: int data; …… public: CA(); …… }; CA::CA():data(0)//……#1……初始化列表方式 { //data = 0;//...
编译器提供的默认构造函数的初始化规则: 在栈和堆中的类对象的内置或复合类型成员变量将为脏数据; 在全局变量区的类对象的内置或复合类型成员变量初始化为0; 类对象成员将调用默认的构造函数来初始化; #...
在头文件的类的定义中定义了一个...1、在构造函数后的参数初始化列表中初始化 2、将const变量同时声明为 static 类型进行初始化。 Eg: #include class CTestA { public: CTestA():m_iSIZE(20) // method 1 { } ~CT
13.6.2 移动构造函数和移动赋值运算符 473 13.6.3 右值引用和成员函数 481 小结 486 术语表 486 第14章 操作重载与类型转换 489 14.1 基本概念 490 14.2 输入和输出运算符 494 14.2.1 重载输出...
13.6.2 移动构造函数和移动赋值运算符 473 13.6.3 右值引用和成员函数 481 小结 486 术语表 486 第14章 操作重载与类型转换 489 14.1 基本概念 490 14.2 输入和输出运算符 494 14.2.1 重载输出...
为了实现一个动态数组类的封装,我们需要考虑几个问题:new/delete的使用、内存分配策略、类的四大函数(构造函数、拷贝构造函数、拷贝赋值运算符、析构函数)、运算符的重载。涉及到的知识点很多,对此本文只做简单...
2 谈谈你对拷贝构造函数和赋值运算符的认识 3 用C++设计一个不能被继承的类 4 简述队列和栈的异同 5 深拷贝和浅拷贝的区别是什么 6 栈上分配内存和堆上分配内存有什么区别? 7 C++ 的一个类中,静态成员函数和普通...