`
weihe6666
  • 浏览: 440178 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

初始化函数列表和构造函数内赋值之区别

    博客分类:
  • C++
C++ 
阅读更多
初始化函数列表和构造函数内赋值之区别


既然构造函数初始化列表和构造函数体内赋值都可以对成员变量赋值,那么二者有何区别,是不是二者等效呢?

一、若类的数据成员是静态的(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的成员函数的调用:一次是缺省构造函数,另一次是赋值。

而用第一种方法(初始化列表)只是一次调用缺省的构造函数,并不会调用赋值函数。会减少不必要的开支,当类相当复杂时,就会看出使用初始化列表的好处。
分享到:
评论

相关推荐

    C++构造函数初始化列表

    构造函数初始化列表是C++中一个非常重要的特性,它允许程序员在对象创建时直接对类中的成员进行初始化,而不是先分配内存再赋值,这在效率和安全性上都有显著优势。 #### 构造函数初始化列表的作用与语法 构造函数...

    成员初始化列表与构造函数体中的区别详细解析

    不同之处在于,使用构造函数初始化列表的版本初始化数据成员,没有定义初始化列表的构造函数版本在构造函数体中对数据成员赋值。 请问这里的初始化数据成员与对数据成员赋值的含义是什么?有什么区别? 我知道在数据...

    解决C++全局变量只能初始化不能赋值的问题

    声明、初始化与赋值的区别: 声明:int a; 初始化:int a = 2;(在声明的时候顺带赋值叫做初始化) 赋值:a = 2; 只有定义(int a;)才分配存储空间,初始化必须要有存储空间来初始化 全局变量在声明时候顺带赋值...

    C++关于构造函数的初始化

    在上面的例子中,`a`(常量成员)和`b`(引用成员)在构造函数的成员初始化列表中被初始化,确保它们在构造函数体执行之前得到正确赋值。 2. **函数体初始化**: 函数体初始化则是在所有数据成员分配内存后,在...

    C++初始化成员列表.

    一方面,使用初始化成员列表可以避免类成员的隐式默认构造函数的调用,避免了多余的构造和赋值操作,从而提高效率。例如,在下面的例子中,MyClass中的abc成员是ABC类的对象,而ABC类只有带参数的构造函数,没有默认...

    C++类构造函数初始化列表

    - **内置数据类型、复合类型(如指针、引用)**:在成员初始化列表和构造函数体内进行初始化或赋值,在性能和结果上基本没有区别。 - **用户定义类型(类类型)**:虽然结果相同,但效率有很大差异。类类型的数据...

    C++ 构造函数初始化列表的好处

    C++ 类对像构造时,需要对类成员变量完成初始化赋值操作。...第三行是初始化列表构造 b1 时调用的复制构造函数。第四行调用了一次默认构造函数……第四行是哪儿来的?  这里需要陈述一下“复制构造函数”和

    C++中成员初始化列表的使用

    本文将详细解释成员初始化列表的概念、用途以及它与传统构造函数内初始化的区别,并通过具体示例来阐述其在特定场景下的应用。 #### 成员初始化列表的基本概念 在C++中,当定义一个类时,可能会包含多种类型的成员...

    第9章类的构造函数、析构函数与赋值函数[文].pdf

    总的来说,理解和正确使用构造函数、析构函数、拷贝构造函数和赋值函数是C++编程中至关重要的技能,它们有助于确保对象的正确初始化和清理,以及在对象复制和赋值时保持数据的一致性和完整性。忽视这些函数的细节...

    C++初始化函数列表详细解析

    原因:C++可以定义引用类型的成员变量,引用类型的成员变量必须在构造函数的初始化列表中进行初始化。对于类成员是const修饰,或是引用类型的情况,是不允许赋值操作的,(显然嘛,const就是防止被错误赋值的,引用...

    程序设计中基于构造函数的对象初始化方法研究.zip_C++_suddenh4l

    3. **构造函数初始化列表**:在构造函数内部,使用初始化列表(ctor initialization list)是一种更高效且推荐的方式来初始化成员变量,而不是在函数体中进行赋值。例如: ```cpp class MyClass { private: int ...

    c++(7) 构造和析构函数

    构造函数与析构函数是C++中非常重要的概念,它们对于确保类实例的正确初始化与清理至关重要。本文将详细介绍构造函数与析构函数的相关知识点。 #### 一、构造函数 构造函数是一种特殊成员函数,其主要任务是在对象...

    cpp代码-C++:初始化列表:2.向构造函数传递参数

    - 初始化列表应优先于构造函数体内的赋值操作,以减少不必要的成员变量初始化。 - 为静态和常量成员提供初始化列表。 - 确保初始化列表中的成员顺序与类定义中的一致。 总之,C++的初始化列表是构造函数的一个...

    C#构造函数的理解

    - **特点**:有参构造函数提供了更灵活的方式来初始化对象,可以在创建对象的同时为对象的属性赋值。 - **示例**:`Monitor` 类的有参构造函数可以用来初始化对象的属性。 ```csharp public Monitor(string height,...

    章构造函数和析构函数PPT学习教案.pptx

    在C++编程语言中,构造函数和析构函数是面向对象程序设计的重要组成部分,它们主要用于对象的初始化和清理工作。本教程将详细讲解这两个概念及其应用。 首先,构造函数是类的一个特殊成员函数,它的主要任务是在...

    C++类成员和数据成员初始化总结

    1. **const、引用和特定类型的成员**(如没有默认构造函数的类类型成员)必须在构造函数的初始化列表中初始化,因为它们不能在构造函数体内赋值。 2. **成员初始化的顺序**并不受它们在构造函数中出现的位置影响,...

    C++ 默认构造函数

    C++ 默认构造函数是编程语言C++中一个关键的概念,主要涉及到类的实例化和对象初始化。当程序员没有显式地定义任何构造函数时,C++编译器会自动为类提供一个默认构造函数,这个构造函数是无参数的,其主要任务仅仅是...

Global site tag (gtag.js) - Google Analytics