首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

C++primer学习笔记(五)

在声明和定义处指定inline都是合法的。类的前向声明一般用来编写相互依赖的类。类定义以分号结束,之后可以跟对象列表。...类中的const成员必须在初始化列表中初始化,无法再构造函数体内赋值。初始化const或引用类型或没有默认构造函数的类类型数据成员的唯一机会是构造函数的初始化列表【冒号开始,逗号分隔】。...初始化顺序由定义顺序决定,而不是初始化列表顺序。 友元:将非公有成员的访问权授予指定的类或函数。friend在类定义内部。友元引入的类名和函数(定义或声明)可以像预先声明的一样使用。...即使定义了其他构造函数,也会合成复制构造函数【能够复制类中的数组】。类成员有指针一般需要显示定义复制构造函数。 声明而不定义成员函数是合法的,但是使用将导致链接失败。...将复制构造函数声明为private可防止复制。定义了复制构造函数,也必须定义默认构造函数。 重载赋值操作符=,隐含的第一个参数this。复制构造函数、赋值操作符、显示析构函数【虚空不算】一般同时出现。

37010

C++:10---再议拷贝构造函数

- -个非引用类型的形参 ●从一个返回类型为非引用类型的函数返回一个对象 ●用花括号列表初始化-一个数组中的元素或--个聚合类中的成员 八、使用=default 与构造函数使用=default一样,拷贝构造函数也可以使用...=default =default的拷贝构造就相当于系统默认的拷贝构造 当在类内使用=default时,函数将隐式地声明为内联,如果不希望是内联函数,就将函数在类外定义 class Sales_data...九、绕过拷贝构造函数 在拷贝初始化过程中,编译器可以(但不是必须)跳过拷贝/移动构造函数,直接创建对象 但是,即使编译器库绕过了拷贝/移动构造函数,但在这个程序点上,拷贝/移动构造函数必须是存在且可访问的...// 调用赋值运算符, 因为b已经初始化过了 十一、需要析构函数的类也需要拷贝和赋值操作 原则:通常,如果一个类需要一个析构函数,我们几乎可以肯定这个类也需要一个拷贝构造函数和一个拷贝赋值运算符...反之亦然一如果一个类需要一个拷贝赋值运算符,几乎可以肯定它也需要一个拷贝构造函数。然而,无论是需要拷贝构造函数还是需要拷贝赋值运算符都不必然意味着也需要析构函数。

74920
  • 您找到你想要的搜索结果了吗?
    是的
    没有找到

    读完某C++神作,我只记下了100句话

    任何字符可以表示为 \ooo【ooo表示一个八进制数】 对象是内存中具有类型的区域。初始化不是赋值,初始化是创建并赋值。...类中的const成员必须在初始化列表中初始化,无法再构造函数体内赋值。初始化const或引用类型或没有默认构造函数的类类型数据成员的唯一机会是构造函数的初始化列表【冒号开始,逗号分隔】。...初始化顺序由定义顺序决定,而不是初始化列表顺序。 友元:将非公有成员的访问权授予指定的类或函数。friend在类定义内部。友元引入的类名和函数(定义或声明)可以像预先声明的一样使用。...即使定义了其他构造函数,也会合成复制构造函数【能够复制类中的数组】。类成员有指针一般需要显示定义复制构造函数。 声明而不定义成员函数是合法的,但是使用将导致链接失败。...将复制构造函数声明为private可防止复制。定义了复制构造函数,也必须定义默认构造函数。 重载赋值操作符=,隐含的第一个参数this。复制构造函数、赋值操作符、显示析构函数【虚空不算】一般同时出现。

    1.4K20

    C++编程经验(12):C++11新特性

    我们以前把指针置空都是: ptr = NULL; NULL是一个宏定义,数值为0。当然不是说用NULL有什么问题,不过新的规范都出来了,就用新规也没什么不好嘛。...默认情况下,Lambda函数总是一个const函数,mutable可以取消其常量性。在使用该修饰符时,参数列表不可省略(即使参数为空); 4.->return-type:返回类型。...用追踪返回类型形式声明函数的返回类型。我们可以在不需要返回值的时候也可以连同符号”->”一起省略。此外,在返回类型明确的情况下,也可以省略该部分,让编译器对返回类型进行推导; 5....---- volatile 如上图所示,所有线程的共享变量都存储在主内存中,每一个线程都有一个独有的工作内存,每个线程不直接操作在主内存中的变量,而是将主内存上变量的副本放进自己的工作内存中,只操作工作内存中的数据...通知方: 获取 std::mutex, 通常是 std::lock_guard 修改共享变量(即使共享变量是原子变量,也需要在互斥对象内进行修改,以保证正确地将修改发布到等待线程) 在 condition_variable

    1K20

    【C++】深入剖析C++11新特性

    C++11中废弃auto原来的用法,将其用于实现自动类型推断。这样要求必须进行显示初始化,让编译器将定义对象的类型设置为初始化值的类型。...不仅仅有移动构造,还有移动赋值: 在bit::string类中增加移动赋值函数,再去调用bit::to_string(1234),不过这次是将bit::to_string(1234)返回的右值对象赋值给...在C++11中更简单,只需在该函数声明加上=delete即可,该语法指示编译器不生成对应函数的默认版本,称=delete修饰的函数为删除函数。...mutable:默认情况下,lambda函数总是一个const函数,mutable可以取消其常量性。使用该修饰符时,参数列表不可省略(即使参数为空)。 ->returntype:返回值类型。...在块作用域中的lambda函数仅能捕捉父作用域中局部变量,捕捉任何非此作用域或者非局部变量都会导致编译报错。 e. lambda表达式之间不能相互赋值,即使看起来类型相同。

    59840

    Dart 简介

    () 的参数)之外,此代码还显示您可以将函数用作参数:顶级 print() 函数是 forEach() 的参数。...} // 将转发到默认构造函数的命名构造函数。 Spacecraft.unlaunched(String name) : this(name, null); // 方法。...重要概念 在继续学习 Dart 语言时,请记住以下事实和概念: 您可以放在变量中的任何内容都是一个 对象 ,并且每个对象都是一个 类 的实例。即使是数字、函数和 null 也是对象。...在 var number = 101 中,number 被推断为 int 类型。 如果您启用了空安全,除非您声明它们可以,否则变量不能包含 null。您可以通过在类型的末尾添加问号(?)...类型的变量可能是整数,也可能是 null。如果您 知道 某个表达式永远不会计算为 null,但 Dart 不同意,您可以添加 ! 来断言它不为 null(如果为 null 则抛出异常)。

    9510

    【C++进阶】C++11的认识与学习

    一.列表初始化 这个要和构造函数的初始化列表区分开。 在C++11中,新增加了列表初始化,即可以用(=){},给所有的内置类型和自定义类型初始化(等号可有可无)。...,就是在调用 initializer_list 的构造函数,C++11为STL容器都添加了有 initializer_list 的构造函数。...使用该修饰符时,参数列表不可省略(即使参数为空)。其实这个用的很少。 ->returntype:返回值类型。用追踪返回类型形式声明函数的返回值类型,没有返回 值时此部分可省略。...捕捉列表不允许变量重复传递,否则就会导致编译错误 在块作用域以外的lambda函数捕捉列表必须为空 lambda表达式之间不能相互赋值 其实,lambda表达式的底层是仿函数,即使两个lambda表达式看起来是一样的...: 移动构造函数 移动赋值运算符重载 一些注意点: 如果没有自己实现移动构造函数,且没有实现析构函数 、拷贝构造、拷贝赋值重载中的任 意一个,那么编译器会自动生成一个默认移动构造。

    16510

    【C++】多态 ① ( 类型兼容性原则与函数重写 | “ 多态 “ 引入 | 函数重写 )

    之后写的代码 ; 2、函数重写 函数重写 : 同时 在 子类 和 父类 中 , 定义 函数原型 相同 的 函数 , 就是 " 函数重写 " , 子类 重写 父类 中的 函数 ; 父类 中 被子类 重写的...函数 , 仍然被 子类 所继承 ; 在 默认的情况下 , 子类 会 隐藏 父类中 被重写的函数 , 如果想要 显示调用 父类 的 被重写的函数 , 可以使用 域作用符 父类名称 :: 被重写的函数()...int x; }; // 子类 class Child : public Parent { public: // 在子类构造函数初始化列表中 调用 父类构造函数 Child(int a, int...将 p 指针指向 子类对象 // 通过 p 指针 调用指向对象的 print 函数 // 结果 - `父类 : x = 1` // 虽然将 子类对象 地址赋值给了 p 指针 // 但是 调用的...<< "父类 : x = " << x << endl; } public: int x; }; // 子类 class Child : public Parent { public: // 在子类构造函数初始化列表中

    20740

    C++11常用的一部分新特性

    C++11中废弃auto原来的用法,将 其用于实现自动类型腿断。这样要求必须进行显示初始化,让编译器将定义对象的类型设置为初 始化值的类型。...注意:C++11给右值分为 纯右值(内置类型) 将亡值(自定义类型) 那么在to_string函数中返回了一个将亡值,如果在进行拷贝构造有些没必要: 那么这里在进行拷贝传值的时候就会传给移动构造函数...在C++11中更简单,只需在该函数声明加上=delete即 可,该语法指示编译器不生成对应函数的默认版本,称=delete修饰的函数为删除函数。...mutable:默认情况下,lambda函数总是一个const函数,mutable可以取消其常量性。使用该修饰符时,参数列表不可省略(即使参数为空)。 ->returntype:返回值类型。...在该函数体内,除了可以使用其参数外,还可以使用所有捕获到的变量。 注意: 在lambda函数定义中,参数列表和返回值类型都是可选部分,而捕捉列表和函数体可以为 空。

    457110

    【C++】C++11常用特性总结

    列表在C++中作用于对象时,同样也可以初始化对象。当然,{}列表在初始化对象的时候会调用对象所属类的构造函数。...下面是C++98中NULL这个宏的定义,由于NULL既可表示字面值0,也可以表示空指针(void*)0,为了便于区分字面值和空指针,在C++11中引入了关键字nullptr,此关键字专门用来表示空指针,...用移动拷贝和移动赋值对比拷贝构造和拷贝赋值就可以看出来,拷贝构造和拷贝赋值即使参数是左值引用,在传参时能够减少拷贝提高效率,但只要涉及到资源申请的时候,拷贝构造和拷贝赋值内部一定是将资源重新拷贝了一份,...所以,在C++11中,容器也都实现了右值版本的移动构造和移动赋值,以便于在某些场景下能够提高效率,如果拷贝的是一个右值,那么就会对应的调用移动构造和移动赋值,将资源进行转移,而不是进行拷贝一份,此时效率就会提高很多...,固定第一个参数为类的匿名对象,这样在使用包装器调用类成员函数的时候,就不需要再显示传一个匿名对象了。

    82140

    【C++】————C++11

    C++11中废弃auto原来的用法,将其用于实现自动类型腿断。这样要求必须进行显示初始化,让编译器将定义对象的类型设置为初始化值的类型。...在C++11中更简单,只需在该函数声明加上=delete即可,该语法指示编译器不生成对应函数的默认版本,称=delete修饰的函数为删除函数。...mutable:默认情况下,lambda函数总是一个const函数,mutable可以取消其常量性。使用该修饰符时,参数列表不可省略(即使参数为空)。 ->returntype:返回值类型。...在该函数体内,除了可以使用其参数外,还可以使用所有捕获到的变量。 在lambda函数定义中,参数列表和返回值类型都是可省略部分,而捕捉列表和函数体可以为空。...在块作用域中的lambda函数仅能捕捉父作用域中局部变量,或者全局变量。 f. lambda表达式之间不能相互赋值,即使看起来类型相同。

    6310

    C++11特性大杂烩

    因为这个迭代器类型由一个类模板来定义,在该类模板未被实例化之前编译器是无法识别这个类型最好也增加一个用initializer_list为参数的赋值运算符重载函数,来支持对列表对象进行赋值。...,移动构造和移动赋值的作用是通过移动右值的资源,减少了拷贝构造次数,减少了损耗万能引用和完美转发万能引用首先需要模板,然后在参数列表中是模板参数 &&图片模板中的&&不代表右值引用,而是万能引用也称折叠引用...,也可以被修改,所以在函数PerfectForward后续的使用中右值会被识别成左值。...,在C++98中,是将函数权限设置为private,且只声明不实现,这样在外部调用时就会报错。...lambda函数捕捉列表必须为空在块作用域中的lambda函数仅能捕捉父作用域中局部变量,捕捉任何非此作用域或者非局部变量都会导致编译报错lambda表达式之间不能相互赋值,即使看起来类型相同lambda

    90950

    【C++】泛型编程 ⑬ ( 类模板示例 - 数组类模板 | 构造函数和析构函数 的 声明与实现 | 普通成员函数 的 声明与实现 | 外部友元函数 的 声明与实现 )

    的 声明与实现 在声明类时 , 前面加上 模板类型声明 template , 说明在类中要使用类型 T ; 在 Array 类中 , 声明 构造函数 , 拷贝构造函数 , 析构函数..., 不需要 显示注明 类型 T ; 声明 构造函数 , 拷贝构造函数 , 析构函数 : template class Array { public: // 有参构造函数...析构函数 : 在 类模板 外部 访问 类模板 中声明的 函数 , 先显示声明 模板类型 template , 然后在下面使用 域作用符 访问 类模板中的 函数 , 域作用符...前面的 类型 , 需要 注明实际类型 , 这里使用 Array:: 访问类模板 中的 函数 ; 注意 : 如果在 函数参数 和 函数返回值 中 , 使用到了 Array 类型 , 那么也必须加上...= len; // 为数组在堆内存中分配内存 // 注意 元素类型为 T m_space = new T[m_length]; cout 构造函数 " << endl;

    52010

    上手指南 | Dart,随用随查

    默认值 未初始化的变量默认值是 null,即使是数字类型也是 null。Dart 中一切皆是对象 Final 和 Const 使用过程中从来都不会被修改的变量,可用 final 或者 const。...,既然有这样运算符,说明他在一定程度上节省了我们的代码 整个运算符是专门用来处理 null 值得,他会提供空指针的相关操作 // b 不为 null,则吧 b 赋值给 a,否则 将 c 赋值给 a a...c; //若 a 为 null,则将 b 赋值给 a a ?? = b; //当 x 不为 nul 时,调用 fun 函数 a?....**匿名函数可以赋值到一个变量中,例如:在一个集合中可以添加或者删除一个匿名函数 main(){ var list = []; list.add(1); list.add(2); list.add...//将匿名函数赋值给变量 var one = (num)=>print(' 值:$num'); one(10); //将普通函数赋值给变量 var two = abc; two

    1.8K50

    【C++】泛型编程 ⑮ ( 类模板示例 - 数组类模板 | 自定义类中持有指针成员变量 )

    char m_name[32] 是 数组类型 , 创建时就直接分配了内存空间 , 即使浅拷贝也可以完成对 该类型对象的 拷贝工作 ; class Student { friend ostream&...* m_name 指针成员 ; 那么需要进行 堆内存管理 , 在 构造函数中 分配堆内存 ; 在 析构函数中 释放堆内存 ; 为了避免 浅拷贝 问题出现 , 需要 进行 等号 = 运算符重载 ; 以及...重写 拷贝构造函数 ; 为了使用 cout 打印该 类对象 , 需要 进行 左移 << 运算符重载 ; 3、改进方向 - 构造函数 在类的 无参构造函数 和 有参构造函数中 , 使用 new 关键字 ,...自动在堆内存中分配内存 , 然后为 堆内存 中的空间赋值 ; Student(){ m_age = 10; // 创建一个数组个数为 1 的数组, 存放 '\0' 值 // 这是一个空字符串...= NULL){ delete[] m_name; m_name = NULL; } } 5、改进方向 - 重载左移运算符 重载左移运算符 , 以便可以在 cout 中打印该类信息 ;

    17710

    【C++】类和对象(附题)

    需要注意的是只有不传参的构造函数是默认构造,如果我们将Stack类中构造改为需要传参的,那Myqueue就会因为没有可用的默认构造报错。对于这种需要传参数的构造函数,我们只能通过初始化列表解决。...对于没有显示在初始化列表初始化的自定义类型成员会调用这个成员类型的默认构造函数,如果没有默认构造会编译错误。...初始化列表总结: 无论是否显示写初始化列表,每个构造函数都有初始化列表; 无论是否在初始化列表显示初始化,每个成员变量都要走初始化列表初始化; ​ ​ • 初始化列表中按照成员变量在类中声明顺序进行初始化...最后将累加结果返回就行。 附加题: 设已经有A,B,C,D 4个类的定义,程序中A,B,C,D构造函数调用顺序为?...Release下,我们发现编译器的优化行为更加激进,这一次连aa都不构造,直接通过将1传给ret构造函数构造ret 及时我们在函数中进行++,编译器也直接为我们算好了值,用最终的值直接去构造出ret。

    8000

    第 13 章 拷贝控制

    用花括号列表初始化一个数组中的元素或一个聚合类中的成员 标准库容器插入元素(insert、push)时,会对元素进行拷贝;而 emplace则是进行直接初始化 在拷贝初始化过程中,编译器可以(但不是必须...编译器略过了拷贝构造函数 在一个构造函数中,成员的初始化是在函数体执行之前完成的,且按照它们在类中出现的顺序进行初始化。...不过,这都并不意味着需要析构函数。 可以通过将拷贝控制成员定义为 =default来显示要求编译器生成合成的版本,不过只能对具有合成版本的成员函数使用。...类的成员的析构函数是删除或不可访问的,则类的合成析构函数被定义为删除的。同时,类的合成拷贝构造函数也会被定义为删除的(否则,就可能创建出无法销毁的对象)。...因此,不能将一个右值引用直接绑定到一个变量上,即使这个变量是右值引用也不行。

    1K50

    C++之类和对象

    ,由编译器自动传递; 其次,重载函数中的 operator= 就是默认成员函数之一 – 赋值重载函数; 注:由于运算符重载函数很多,情况也比较复杂,所以我们将运算符重载的详细细节 (比如引用做返回值、引用做参数...: 可以看到对于内置类型_a当我不在初始化列表中初始化它,编译器就会用一个随机值来初始化,而我不在初始化列表中初始化,编译器就会自己去找自定义类型自己的默认构造函数,当自定义类型既没有在初始化列表中显示定义又没有默认构造函数时就会报错...: 3.如果类中包含以下成员就必须要显示定义在初始化列表中: 1.引用成员变量 2.const成员变量 3.自定义类型成员(且该类没有默认构造函数时) **引用是给变量取别名,一旦它成为了某一个变量的别名就不能再成为另一个变量的别名...**前面说了构造函数只是赋值并不是初始化,真正的初始化只有在初始化列表中,所以引用成员变量和const成员变量都必须显示的写在初始化列表中。...构造函数的隐式类型转换 在C++98中,单参数的构造函数也支持隐式函数重载,这里说的单参数是指只需要传一个参数的函数,包括单参数,全缺省和半缺省。

    1.2K00

    【C++】‘类与对象‘-三部曲——(4)(23)

    【 '类与对象'-三部曲】的大纲主要内容如下: 如标题所示,本章是【 '类与对象'-三部曲】三章中的第二章节——类章节,主要内容如下: 一.类 C++兼容C,C语言中的结构体strcut也算是一种类,是...默认生成的拷贝构造函数为浅拷贝可以直接用; 而Stack类为自定义类型,其中有a指针指向一块新开辟的空间。...(如果重载成全局函数,编译器会生成一个默认运算符重载) 用户没有显示实现时,编译器会生成一个默认赋值运算符重载,以值的方式(浅拷贝)逐字节拷贝。...一.初始化列表和构造函数的关系 引入:构造函数调用之后,对象中已经有了一个初始值,但是不能将其称为对对象中成员变量的初始化, 构造函数体中的语句只能将其称为赋初值,而不能称作初始化。...五.成员变量在初始化列表中的初始化顺序 成员变量在类中声明次序就是其在初始化列表中的初始化顺序,与其在初始化列表中的先后次序无关 图示:

    15910

    【C++高阶】:C++11的深度解析上

    统一的列表初始化 1.1 { }初始化 在C++98中,标准允许使用花括号{}对数组或者结构体元素进行统一的列表初始值设定。...new表达式中 int* pa = new int[4]{ 0 }; return 0; } 我们的自定义创建的对象也可以使用列表初始化方式调用构造函数初始化 class Date{ public:...C++11中废弃auto原来的用法,将其用于实现自动类型腿断。这样要求必须进行显示初始化,让编译器将定义对象的类型设置为初始化值的类型。...如果你没有自己实现移动赋值重载函数,且没有实现析构函数 、拷贝构造、拷贝赋值重载中的任意一个,那么编译器会自动生成一个默认移动赋值。...在C++11中更简单,只需在该函数声明加上=delete即可,该语法指示编译器不生成对应函数的默认版本,称=delete修饰的函数为删除函数。

    7110
    领券