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

【C++】构造函数初始列表 ① ( 类对象作为成员变量构造函数问题 | 构造函数初始列表语法规则 )

一、类对象作为成员变量构造函数问题 1、问题描述 如果 一个类 A 对象 作为 另外一个类 B 成员变量 , 在以下场景会报错 : 为类 A 定义 有参 构造函数 , 那么 A 无参默认构造函数就失效了...; 此时使用 默认无参构造函数 初始 B , 就会报错 ; 在一个类中 , 其成员变量是 带有参构造函数 类型 , 这种情况下没有调用 有参构造函数机会 , 此时就会出现 编译报错情况 ; 在下面的代码中...无参构造函数创建 A 对象 , 但是 A 无参构造函数无法使用 , 必须使用 A 有参构造函数 , 这里就出现问题 , 报错 “B::B(void)”: 由于 数据成员“B::m_a”不具备相应...就是 C++ 中 构造函数 初始列表 ; 2、错误代码示例 代码示例 : #include "iostream" using namespace std; class A { public: /...(成员变量值) , 成员变量名称(成员变量值) { // 构造函数内容 } 构造函数初始列表 位置在 构造函数 参数列表之后 , 冒号 : 与花括号 {} 之间 ; 使用 逗号 , 分隔 ;

49730

【C++】vector模拟实现(SGI版本)

在实现完n个value构造构造函数之后,如果我们此时用10个int类型数字1来构造对象v1,实际会报错,报错原因其实是由于函数匹配优先级所导致实参无法正确匹配相应构造函数。...而对于迭代器区间作为参数构造来讲,函数模板参数InputIterator只需要进行一次类型推导即可完成匹配,所以用10个1来构造,实际匹配构造函数是迭代器区间作为参数构造函数,而在匹配构造函数中...//1也需要进行类模板显示实例,优先级并没有同类型参数函数模板高,函数模板只需要一次推导参数类型即可匹配成功。...//2.但是如果匹配函数模板,则解引用int类型就会发生错误,非法间接寻址。...无论是代码可读性还是实用性角度来讲,现代写法都更胜一筹,这里利用形参对象v迭代器来构造临时对象tmp,然后将对象tmp和* this进行交换,为了防止对象tmp离开函数栈帧销毁造成野指针访问问题

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

【笔记】《深入理解C++11》(上)

其他构造函数通过带有默认值委派构造来调用这个目标构造函数 千万小心环形委派, 会导致编译错误 委派构造函数使得构造函数模板编程也成为一种可能, 通过让模板构造函数成为委派构造函数, 我们可以很容易地接受多种不同类型参数进行相同底层初始...在C++11标准中提出SFINEA动机是当年C++98中并没有对这个规则进行标准描述, 因此各个编译器对于函数模板匹配规则都是混乱, 因此新标准提出SFINEA来使程序员能按照自己想象来理解编译器并令其能精确匹配我们所需要函数...可行保留并计算匹配精确度, 选择最佳匹配候选函数作为结果 如果存在两个相同匹配等级参数列, 优先保留普通函数 完全找不到匹配函数或者产生二义性, 引发error 这个尝试进行参数替换过程中编译器只发生...failure, 不会引发error, 直到完成所有尝试 基础来说, SFINEA使得模板实例过程在各个编译器上都能表现出一样效果, 且避免在不相关模板可见实例化出错误程序....SFINEA原因int对f1尝试不算做实例error, 而属于匹配过程中一次failure f(10); } 基于对这个匹配过程标准描述, 我们可以无关编译器地对模板匹配可行性进行判断

1.8K20

C ++ 中不容忽视 25 个 API 错误设计!

错误#4:不将API中移动构造函数和移动赋值运算符标记为noexcept 一般来说,预计不会抛出移动操作。你基本上是对象中窃取了一堆指针并将它组合到你目标对象,理论上它不应该抛出。...错误#9:使用隐式模板实例化时,使用模板实现细节来混淆公共头文件 在隐式实例中,模板代码内部必须放在头文件中。没有其他办法。...它好处是保持主要公共头文件不受实现细节影响,同时将内部细节必要暴露,隔离到明确指定为包含私有细节单独头文件。 错误#10:当用例已知,不使用显式模板实例 为什么这是一个错误?...这可能会在调试过程中造成巨大问题,因为这会在客户尝试使用AP调试代码隐藏客户端有价值信息,因为他们只会看到调试器中使用量值9.8,而没有任何描述性名称。 如何解决这个问题?...错误#15:对外来(不是你自己对象类型使用前声明 为什么这是一个错误? 对不属于你API对象使用前声明可能会以意外方式中断客户端代码。

1.5K20

《JavaScript启示录》(笔记)

,最好是保持构造函数名称第一个字符大写; 7)如果创建一个构造函数,但没有使用new关键字进行调用,那么this值将引用包含该构造函数“父对象”; 8)在针对字符串、数字和布尔值使用字面量值,只有在该值被视为对象情况下才会创建实际复杂对象...; 9)在尝试使用与构造函数有关联方法或检索属性,JavaScript会在幕后为字面量值创建一个包装器对象,以便将该值视为一个对象,调用方法以后,JavaScript即抛弃包装器对象,该值返回字面量类型...; 9)当在prototype对象方法内部使用this关键字,this可用于引用实例,如果该实例不包含所要查找属性,则继续在原型上查找; 10)如果函数传递意想不到参数(那些在创建函数没有被定义参数...),不会发生错误,可以arguments对象访问这些参数; 11)arguments对象是一种类数组对象,它包含所有传递给函数参数; 12)arguments对象拥有名为callee属性,它是对当前执行函数引用...函数原型属性 1)prototype属性是JavaScript为每个Function()实例创建一个对象; 2)原型链返回在链中找到第一个匹配结果; 3)当试图访问一个对象属性,它会检查该属性对象实例

33620

【C++】内存管理和模板基础(new、delete、类及函数模板

自定义类型 new原理: 调用operator new函数申请空间 在申请空间上执行构造函数,完成对象构造 delete原理: 在空间上执行析构函数,完成对象中资源清理工作 调用operator...因为内存池分配出内存没有初始,所以如果是自定义类型对象,需要使用new定义表达式进行显示调构造函数进行初始 使用格式: new (place_address) type或者new (place_address...,new不需要,但是new需 要捕获异常 申请自定义类型对象,malloc/free只会开辟空间,不会调用构造函数与析构函数,而new 在申请空间后会调用构造函数完成对象初始,delete在释放空间前会调用析构函数完成...用不同类型参数使用函数模板,称为函数模板实例模板参数实例化分为:隐式实例和显式实例。 1....显式实例:在函数名后中指定模板参数实际类型 模板参数匹配原则 一个非模板函数可以和一个同名函数模板同时存在,而且该函数模板还可以被实例化为这个非模板函数 对于非模板函数和同名函数模板,如果其他条件都相同

6810

《C++Primer》第十八章 用于大型程序工具

栈展开过程沿着嵌套函数调用链不断查找,直到找到了与异常匹配catch子句为止,或者也可能一直没有找到匹配catch,则退出主函数后查找过程终止。...如果异常发生在构造函数中,则当前对象可能只构造了一部分(有些成员已经初始化了,另一些成员在异常发生前也许还没有初始)。即使某个对象构造了一部分,我们也要确保已构造成员能被正确地销毁。...1.4 异常对象 抛出一个指向局部对象指针几乎肯定是一种错误行为 抛出一条表达式,该表达式静态编译类型决定了异常对象类型(如果一条throw表达式解引用一个基类指针,而该指针实际指向是派生类对象...构造函数与虚继承 在虚派生中,虚基类是由最低层派生类初始。以我们程序为例,当创建Panda对象,由Panda构造函数独自控制ZooAnimal初始过程。...如果ZooAnimal没有默认构造函数,那么代码将发生错误。 虚基类总是先于非虚基类构造,与它们在继承体系中次序和位置无关。

1.3K20

《逆袭进大厂》第三弹之C++提高篇79问79答

这种模式在没有模板情况下运行良好,但遇到模板就傻眼了,因为模板仅在需要时候才会实例化出来。...然而当实现该模板.cpp文件中没有用到模板实例,编译器懒得去实例,所以,整个工程.obj中就找不到一行模板实例二进制代码,于是连接器也黔驴技穷了。...1) C++中异常情况: 语法错误(编译错误):比如变量未定义、括号不匹配、关键字拼写错误等等编译器在编译能发现错误,这类错误可以及时被编译器发现,而且可以及时知道出错位置及原因,方便改正。...有三种情况会以一个对象内容作为另一个对象初值: 1) 对一个对象做显示初始操作,X xx = x; 2) 当对象被当做参数交给某个函数; 3) 当函数传回一个类对象; 1) 如果一个类没有拷贝构造函数...把你知道都说一说 1) 构造函数构造函数初始对象,派生类必须知道基类函数干了什么,才能进行构造;当有虚函数,每一个类有一个虚表,每一个对象有一个虚表指针,虚表指针在构造函数中初始; 2)

2.2K30

Chapter 5: Rvalue References, Move Semantics, PF

在合适条件下,即便存在模板构造函数可以通过实例来产生拷贝或者移动构造函数,编译器也会自动产生拷贝或者移动构造函数。...上述auto cloneOfP(p)语句似乎应该是调用拷贝构造函数,但是实际上会调用完美转发构造函数,然后会用Person对象去实例Personstring成员,然而并没有这种匹配规则,马上报错!...如果对传入对象p加上const修饰,那么虽然模板函数虽然会被实例化成为一个接收const类型Person对象函数,但是具有在const类型参数所有重载函数中,C++中重载解析规则是:当模板实例函数和非模板函数同样都能匹配一个函数调用...:当传入参数类型是Person,应该调用拷贝构造函数,也就是要禁用模板;否则应该启用模板,将函数调用匹配到通用引用构造函数中。...而标准规定:函数模板传递一个花括号初始参数,而模板参数又没有指定参数类型为std::initializer_list,那么这就是一个不可推导情况。

5.1K40

第 18 章 用于大型程序工具

当执行一个 throw,跟在 throw后面的语句将不再被执行,相反程序控制权 throw转移到与之匹配 catch模块。...除了下列允许类型转换外,包括标准算术类型转换和类类型转换在内其他所有转换规则都不能在匹配过程中使用。 允许非常量常量类型转换。 允许派生类基类类型转换。...模板特例必须定义在原始模板所属命名空间中,在命名空间中声明了特例后,就能在命名空间外部定义它了。...在 C++11新标准中,允许派生类一个或几个基类中继承构造函数,但是如果多个基类中继承了相同构造函数(即形参列表完全相同),则程序将产生错误。...含有虚基类对象构造顺序与一般顺序稍有区别:首先使用提供给最低层派生类构造函数初始值初始对象虚基类子部分,接下来按照直接基类在派生列表中出现次序依次对其进行初始

97850

第 18 章 用于大型程序工具

当执行一个 throw,跟在 throw后面的语句将不再被执行,相反程序控制权 throw转移到与之匹配 catch模块。...除了下列允许类型转换外,包括标准算术类型转换和类类型转换在内其他所有转换规则都不能在匹配过程中使用。 允许非常量常量类型转换。 允许派生类基类类型转换。...模板特例必须定义在原始模板所属命名空间中,在命名空间中声明了特例后,就能在命名空间外部定义它了。...在 C++11新标准中,允许派生类一个或几个基类中继承构造函数,但是如果多个基类中继承了相同构造函数(即形参列表完全相同),则程序将产生错误。...含有虚基类对象构造顺序与一般顺序稍有区别:首先使用提供给最低层派生类构造函数初始值初始对象虚基类子部分,接下来按照直接基类在派生列表中出现次序依次对其进行初始

89420

【C++笔试强训】第七天

A 构造函数可以声明返回类型 B 构造函数不可以用private修饰 C 构造函数必须与类名相同 D 构造函数不能带参数 回顾一下构造函数特性:构造函数没有返回值,必须和类名相同,且不能带参数...一般情况下,构造函数权限都是public,因为在类外创建对象,编译器要调用构造函数(特殊:单例模式 —— 一个类只能创建一个对象,将构造函数设置为private) 对比选项,答案选C 有一个类A,...,放在类外) 必须在初始列表中初始: 1.const修饰成员变量 2.引用类型成员变量 3.类类型对象,该类没有默认构造函数 所以答案选B 有如下类模板定义:() template...对象,因为是this指针,所以选D 下面有关友元函数与成员函数区别,描述错误是?...A 类 B 函数 C 模板类 D 对象模板使用实际上是类模板实例化成一个具体类 ---- 编程题 合法括号序列判断 匹配不成功 1.当前字符不是括号字符 2.括号匹配不完整 多出了左半边

15440

C++11常用新特性快速一览

C++11 还把初始列表概念绑定到了类型上,并将其称之为 std::initializer_list,允许构造函数或其他函数像参数一样使用初始列表,这就为类对象初始与普通数组和 POD 初始方法提供了统一桥梁...并且,我们没有办法通知编译器不要触发模板实例。...在这里,我们并没有真正复制,所以我们把这个构造函数叫做“转移构造函数”(move constructor),他工作就是把资源从一个对象转移到另一个对象,而不是复制他们。...没有必要复制他,因为 x+y 是右值,再次,右值指向对象中转移是没有问题。 总结一下:复制构造函数执行是深度拷贝,因为源对象本身必须不能被改变。...第三行编译没有问题,因为 make_triangle() 是右值,转移构造函数会将临时对象所有权转移给对象 c,这正是我们需要

2.5K50

《Effective Modren C++》 进阶学习(上)

作为对比,使用有参数构造函数。 Widget w1(10); // 没问题,使用实参10调用Widget一个构造函数 需要初始一个无参数构造函数对象,会变成函数声明。...编译错误!要求变窄转换 只有当传入参数在编译器上无法转换成std::initializer_list中T类型,才会匹配普通构造函数。...w4{10, 5.0}; // 使用花括号初始,调用第二个构造函数 最后在使用空参数{}初始化时,会匹配默认构造函数,只有传入{}才会匹配initializer_list构造函数。...当使用{}初始无参数,会优先匹配默认构造函数,如果要匹配std::initializer_list构造函数,需要传入{}。 8....constexpr常量可以在编译被用作常量表达式,例如作为数组大小、模板参数或其他需要常量表达式上下文中使用。这样可以提高代码灵活性和可读性。 编译错误检查。

17020

《逆袭进大厂》之C++篇49问49答

当用于类类型对象,初始拷贝形式和直接形式有所不同:直接初始直接调用与实参匹配构造函数,拷贝初始总是调用拷贝构造函数。...在构造,根据对象类型去初始虚指针vptr,从而让vptr指向正确虚表,从而在调用虚函数,能找到正确函数 (3)所谓合适时机,在派生类定义对象,程序运行会自动调用构造函数,在构造函数中创建虚表并对虚表初始...在构造子类对象,会先调用父类构造函数,此时,编译器只“看到了”父类,并为父类对象初始虚表指针,令它指向父类虚表;当调用子类构造函数,为子类对象初始虚表指针,令它指向子类虚表 (4)当派生类对基类函数没有重写...而当一个表达式涉及到类保护成员或私有成员,宏就不能实现了。 40、构造函数、析构函数、虚函数可否声明为内联函数 首先,将这些函数声明为内联函数,在语法上没有错误。...explicit 关键字作用于单个参数构造函数 被explicit修饰构造函数类,不能发生相应隐式类型转换 45、什么情况下会调用拷贝构造函数 用类一个实例对象去初始另一个对象时候 函数参数是类对象

1.9K10

C++ 特性使用建议

二者只进行了转换,没有移动对象。 3.函数重载 (1)仅在输入参数类型不同、功能相同时使用重载函数(含构造函数),当使用具有默认形参值函数(方法)重载形式,需要注意防止二义性。...优点: 有了流,在打印不需要关心对象类型,不用担心格式字符串与参数列表不匹配,并且流构造和析构函数会自动打开和关闭对应文件。 缺点: 流使得 pread() 等功能函数很难执行。...p = {1,2}; C++11 开始,该特性得到进一步推广,任何对象类型都可以被列表初始。...,哪怕没有接收 std::initializer_list 构造函数。...还需要额外注意在用户错误使用你模板代码时候需要输出更人性出错信息。

1.6K20

《逆袭进大厂》之C++篇49问49答(绝对干货)

当用于类类型对象,初始拷贝形式和直接形式有所不同:直接初始直接调用与实参匹配构造函数,拷贝初始总是调用拷贝构造函数。...在构造,根据对象类型去初始虚指针vptr,从而让vptr指向正确虚表,从而在调用虚函数,能找到正确函数 (3)所谓合适时机,在派生类定义对象,程序运行会自动调用构造函数,在构造函数中创建虚表并对虚表初始...在构造子类对象,会先调用父类构造函数,此时,编译器只“看到了”父类,并为父类对象初始虚表指针,令它指向父类虚表;当调用子类构造函数,为子类对象初始虚表指针,令它指向子类虚表 (4)当派生类对基类函数没有重写...而当一个表达式涉及到类保护成员或私有成员,宏就不能实现了。 40、构造函数、析构函数、虚函数可否声明为内联函数 首先,将这些函数声明为内联函数,在语法上没有错误。...explicit 关键字作用于单个参数构造函数 被explicit修饰构造函数类,不能发生相应隐式类型转换 45、什么情况下会调用拷贝构造函数 用类一个实例对象去初始另一个对象时候 函数参数是类对象

2.5K40

真没想到nullptr和NULL得区别,大了去了

第3章 转向现代C++ 条款7:在创建对象注意区分()和{} //创建对象时候注意区分 () 和 {} //指定初始方式有:小括号,等号,大括号 //情况1:内建型别来说 int 初始和赋值没有区别...WidgetA w11(10);//构造函数 WidgetA w22();//调用一个没有形参构造函数,结果变成声明一个函数而非对象 WidgetA w33{};//函数形参不能使用大括号来指定形参列表...,所有使用大括号来完成对象默认构造没有问题 //大括号解决第三类问题:构造函数形参中 具备 std::initializer_list型别 //1, 如果没有以上型别,() 和 {} 没有区别 class...// 在构造函数重载决议期间,只要有任何可能,大括号初始物就会与带有std: : initializer_ list 型别的形参相匹配,即使其他重载版本有着貌似更 加匹配形参表 。...,调用了删除函数 if(isLucky(true))//错误 if(isLucky(3.5f))//错误 //优点3:删除函数可以阻止那些不应该进行得模板具现,private成员函数做不到 //假设需要一个和内建指针协作得模板

1.7K30

【笔记】《C++Primer》—— 第三部分:类设计者工具

构造函数来类型转换,则拷贝初始还是直接初始就无关紧要了 析构函数行为与构造函数相反,会自动销毁掉非static成员和调用成员析构 析构函数没有参数列表,所以成员销毁行为完全依赖于成员自己 析构会在变量离开作用域或母构件销毁销毁...,派生类一般在构造函数开始地方调用基类构造函数,让基类来初始自己成员 静态类型是变量本身代码中类型,在编译决定,动态类型是变量在内存中对象类型,在运行时才能决定。...forward函数,能恢复被右值引用参数去除右值引用属性 在没有歧义情况下,永远会调用发生了最少改变,最精确匹配,最不需要调用自定义类型转换,最不需要调用模板那个重载,即“更特例” 可变参数模板就是一个能接受数目可变类型也可变参数类...即使我们需要特例所有的类型参数也要保留一个空尖括号做标记 完全模板特例本质是模板一个实例,而不是重载,因此特例不会影响函数匹配。...但如果只是部分特例模板则仍然是模板,则依然会参与匹配 我们也可以特例模板,此时必须在原模板定义命名空间中特例它。

1.7K10
领券