C++深入讲解初始化列表的用法

目录
  • 一、小问题
  • 二、类成员的初始化
  • 三、类中的 const 成员
  • 四、初始化与赋值的不同
  • 五、小结

一、小问题

下面的类定义是否合法? 如果合法,ci 的值是什么,存储在哪里?

下面编写代码一探究竟(代码1):

#include <stdio.h>

class Test
{
private:
    const int ci;
public:
    Test()
    {
        ci = 10;
    }
    int getCI()
    {
        return ci;
    }
};

int main()
{
    Test t;

    printf("t.ci = %d\n", t.getCI());

    return 0;
}

可以看到,编译报错,ci 没有被初始化,如果要初始化,就得在 test() 那里进行,且看下节初始化列表。

二、类成员的初始化

C++ 中提供了初始化列表对成员变量进行初始化

语法规则

所以代码 1 可以写成:

#include <stdio.h>

class Test
{
private:
    const int ci;
public:
    Test() : ci(10)
    {
        //ci = 10;
    }
    int getCI()
    {
        return ci;
    }
};

int main()
{
    Test t;

    printf("t.ci = %d\n", t.getCI());

    return 0;
}

这样编译就能通过,得到想要的结果:

注意事项

  • 成员的初始化顺序与成员的声明顺序相同
  • 成员的初始化顺序与初始化列表中的位置无关
  • 初始化列表先于构造函数的函数体执行

下面看一段初始化列表使用的代码:

#include <stdio.h>

class Value
{
private:
    int mi;
public:
    Value(int i)
    {
        printf("i = %d\n", i);
        mi = i;
    }
    int getI()
    {
        return mi;
    }
};

class Test
{
private:
    Value m2;
    Value m3;
    Value m1;
public:
    Test() : m1(1), m2(2), m3(3)
    {
        printf("Test::Test()\n");
    }
};

int main()
{
    Test t;

    return 0;
}

输出结果如下:

这段代码很好的将上面的注释事项体现出来了,初始化顺序是 m1,m2,m3,输出顺序确是 m2,m3,m1,并且构造函数的函数体后于初始化列表的执行。

三、类中的 const 成员

  • 类中的 const 成员会被分配空间的
  • 类中的 const 成员的本质是只读变量
  • 类中的 const 成员只能在初始化列表中指定初始值

编译器无法直接得到 const 成员的初始值,因此无法进入符号表成为真正意义上的常量。

下面看一段代码:

#include <stdio.h>

class Value
{
private:
    int mi;
public:
    Value(int i)
    {
        printf("i = %d\n", i);
        mi = i;
    }
    int getI()
    {
        return mi;
    }
};

class Test
{
private:
    const int ci;
    Value m2;
    Value m3;
    Value m1;
public:
    Test() : m1(1), m2(2), m3(3), ci(100)
    {
        printf("Test::Test()\n");
    }
    int getCI()
    {
        return ci;
    }
    int setCI(int v)
    {
        int* p = const_cast<int*>(&ci);

        *p = v;
    }
};

int main()
{
    Test t;

    printf("t.ci = %d\n", t.getCI());

    t.setCI(10);

    printf("t.ci = %d\n", t.getCI());

    return 0;
}

下面为输出结果:

这段代码说明 const 不是真正意义上的常量,只是只读变量。

四、初始化与赋值的不同

  • 初始化:对正在创建的对象进行初值设置
  • 赋:对已经存在的对象进行值设置

五、小结

  • 类中可以使用初始化列表对成员进行初始化
  • 初始化列表先于构造函数体执行
  • 类中可以定义 const 成员变量
  • const 成员变量必须在初始化列表中指定初值
  • const 成员变量为只读变量

到此这篇关于C++深入讲解初始化列表的用法的文章就介绍到这了,更多相关C++ 初始化列表内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • C++11中列表初始化机制的概念与实例详解

    目录 概述 实现机制详解 POD类型的列表初始化 含有构造函数的类的列表初始化(C++11) 列表初始化用于函数返回值 引入std::initializer_list 代码验证 应用 列表初始化防止类型收窄 总结 概述 定义:列表初始化是C++11引入的新标准,目的是统一初始化方式 C++11以前只能使用列表初始化来初始化内置类型数组和POD类型对象,C++11中列表初始化可以用于初始化任何类型对象 POD(plain old data)类型:仅由内置类型变量构成且不含指针的类,简单来说是可以直

  • C++11中初始化列表initializer lists的使用方法

    C++11引入了初始化列表来初始化变量和对象.自定义类型,如果想用初始化列表就要包含initializer_list头文件. C++11将使用大括号的初始化(列表初始化)作为一种通用初始化方式,可用于所有类型.初始化列表不会进行隐式转换. C++11提供的新类型,定义在<initializer_list>头文件中. template< class T > class initializer_list; 先说它的用处吧,然后再详细介绍一下. 首先有了initializer_list之

  • C++构造函数的初始化列表详解

    目录 1.问题 2.解决方法(初始化列表) 3.顺序问题 总结 1.问题 class A { private: int m_a; public: A(int a) { cout << "A(int a)......." << endl; m_a = a; } void print() { cout <<"m_a=" << m_a << endl; } }; class B { private: int m_

  • C++使用初始化列表的方式来初始化字段的方法

    几个月之前,接触Android recovery源代码的时候,看ScreenRecoveryUI类的时候,那时候C++基础还不是特别好,一直不明白以下的初始化方式: 下面这个是Recovery的一个构造函数,代码位于:screen_ui.cpp,它的类的实现在screen_ui.h. 如下这个ScreenRecoveryUI类,这个类是继承于RecoveryUI类的: 这个文件在screen_ui.h class ScreenRecoveryUI : public RecoveryUI { pu

  • C++成员初始化列表

    文章转自: 公众号:Coder梁(ID:Coder_LT) 除了可以使用构造函数Classy::Classy(int n, int m): mem1(n), mem2(0), mem3(n*m+2) {    ...};类成员进行初始化之外,C++还提供了另外一种初始化的方法,叫做成员初始化列表. 我们假设Classy是一个类,而mem1,mem2和mem3都是这个类的数据成员,那么类构造函数可以写成: Classy::Classy(int n, int m): mem1(n), mem2(0)

  • C++11新特性之列表初始化的具体使用

    目录 统一的初始化方法 列表初始化的一些使用细节 初始化列表 1.任何长度的初始化列表 2.std::initialzer-list的使用细节 列表初始化防止类型收窄 在我们实际编程中,我们经常会碰到变量初始化的问题,对于不同的变量初始化的手段多种多样,比如说对于一个数组我们可以使用 int arr[] = {1,2,3}的方式初始化,又比如对于一个简单的结构体: struct A { int x; int y; }a={1,2}; 这些不同的初始化方法都有各自的适用范围和作用,且对于类来说不能

  • 解析之C++的列表初始化语法

    聚合初始化 先从std::array的内部实现说起.为了让std::array表现得像原生数组,C++中的std::array与其他STL容器有很大区别--std::array没有定义任何构造函数,而且所有内部数据成员都是public的.这使得std::array成为一个聚合(aggregate). 对聚合的定义,在每个C++版本中有少许的区别,这里简单总结下C++17中定义:一个class或struct类型,当它满足以下条件时,称为一个聚合[1]: 没有private或protected数据成

  • 简述C++11就地初始化与列表初始化

    1.就地初始化 1.1简介 在C++11之前,只能对结构体或类的静态常量成员进行就地初始化,其他的不行. class C { private: static const int a=10; //yes int a=10; //no } 在C++11中,结构体或类的数据成员在申明时可以直接赋予一个默认值,初始化的方式有两种,一是使用等号"=",二是使用大括号列表初始化的方式.注意,使用参考如下代码: class C { private: int a=7; //C++11 only int

  • C++深入讲解初始化列表的用法

    目录 一.小问题 二.类成员的初始化 三.类中的 const 成员 四.初始化与赋值的不同 五.小结 一.小问题 下面的类定义是否合法? 如果合法,ci 的值是什么,存储在哪里? 下面编写代码一探究竟(代码1): #include <stdio.h> class Test { private: const int ci; public: Test() { ci = 10; } int getCI() { return ci; } }; int main() { Test t; printf(&

  • C++示例讲解初始化列表方法

    目录 定义 特性 初始化阶段 计算阶段 成员变量的初始化顺序 定义 我们先来看一个例子 Date(int year, int month, int day)//带参构造函数 :_year(year) , _month(month) , _day(day) {} 这是一个简单的初始化列表案例,以一个冒号开始,接着是一个以逗号分隔的数据成员列表,每个"成员变量"后面跟一个放在括 号中的初始值或表达式. 特性 A.初始化列表能只能初始化一次,多次初始化会报错 Date(int year =

  • React Native中ScrollView组件轮播图与ListView渲染列表组件用法实例分析

    本文实例讲述了React Native中ScrollView组件轮播图与ListView渲染列表组件用法.分享给大家供大家参考,具体如下: 1.Scroll View ScrollView是React Native提供的滚动视图组件,渲染一组视图,用户可以进行滑动响应交互,其常用属性如下: 滚动的偏移量:通过event.nativeEvent.contentOffset.x可以得到水平偏移量. horizontal={bool},属性为true时,所有子视图在水平方向排列,否则在纵向排列.默认为

  • C语言实例梳理讲解常用关键字的用法

    目录 一.C语言关键字详解 1. sizeof 2. const 3. static 4. extern 5. volatile 6. typedef 7. enum 8. continue 9. break 一.C语言关键字详解 1. sizeof sizeof相信大家并不陌生,其作用就是计算变量所占用的内存空间大小.sizeof的用法看着和函数很相似,但sizeof的真实身份确是:sizeof既是关键字,也是运算符,但不是函数! 这点需要大家牢记.还有非常重要的一点就是 sizeof中的表示

  • C语言示例讲解for循环的用法

    目录 1.循环语句for的语法 2.for循环中的break以及continue 3.for语句的循环变量控制的一些建议 4.for循环的变种 5.题目 1.循环语句for的语法 for (表达式1;表达式2;表达式3)    循环; 其中,表达式1是初始化:表达式2是判断:表达式3是调整. 示例:用for循环打印1-10. int main() { int i = 0; for (i = 1; i < 11; i++) printf("%d ",i); return 0; }

  • Python简明讲解filter函数的用法

    目录 一.filter函数的定义 二.filter函数实例 求一个序列中大于零的元素组成的新序列 求序列中非零数组成的新序列 求字典中大于2的键组成的新序列 求100以内既是3的倍数又是奇数的正整数 任何事情都是由量变到质变的过程,学习Python也不例外.只有把一个语言中的常用函数了如指掌了,才能在处理问题的过程中得心应手,快速地找到最优方案. 一.filter函数的定义 filter函数是Python中常用的内置函数,调用无需加载库,直接使用即可.它主要用来根据特定条件过滤迭代器中不符合条件

  • C++超详细讲解强制类型转换的用法

    目录 static_cast dynamic_cast const_cast reinterpret_cast static_cast static_cast<type-id>(expression) 将 expression 转换为 type-id 类型.static_cast 是静态类型转换,发生在编译期.这种转换不会进行运行时的动态检查(RTTI),因而这种转换可能是不安全的.static_cast 典型应用场景如下: 1. 类的层级结构中,基类和子类之间指针或者引用的转换. 上行转换(

  • Java超详细分析讲解final关键字的用法

    目录 基本介绍 final细节01 final细节02 基本介绍 final 可以修饰类.属性.方法和局部变量. 在某些情况下,程序员可能有以下需求,就会使用到final: Base Sub 类 1)当不希望类被继承时,可以用final修饰. 2)当不希望父类的某个方法被子类覆盖/重写(override)时,可以用final关键字 修饰.[案例演示:访问修饰符 final 返回类型方法名] 3)当不希望类的的某个属性的值被修改,可以用final修饰.[案例演示: public final dou

  • C++之谈谈构造函数的初始化列表

    目录 一.引入 二.初始化的概念区分 三.语法格式及使用 四.注意事项[] 五.总结与提炼 一.引入 我们知道,对于下面这个类A的成员变量_a1和_a2属于[声明],还没有在内存中为其开辟出一块空间以供存放,真正开出空间则是在[定义]的时候,那何时定义呢?也就是使用这个类A去实例化出对象的时候 这个对象的空间被开出来了,难道里面的成员变量就一定开出空间了吗?这一点我们很难去通过调试观察 class A { public: int _a1; //声明 int _a2; }; int main(vo

  • Android列表对话框用法实例分析

    本文实例讲述了Android列表对话框用法.分享给大家供大家参考.具体如下: main.xml布局文件: <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:la

随机推荐