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

为什么GCC在匹配函数时会查看私有构造函数?

在C++中,当我们尝试使用一个类的对象时,我们需要确保该类具有可访问的构造函数。如果一个构造函数被声明为私有(private),那么它将无法在类的外部被访问。因此,当编译器尝试匹配一个函数时,它需要检查所有可用的构造函数,包括私有的构造函数。

这是因为C++标准要求编译器在匹配函数时必须考虑所有可访问的构造函数。如果一个构造函数被声明为私有,那么它将无法在类的外部被访问,但它仍然可以被类的成员函数和友元函数访问。因此,为了确保匹配函数的正确性,编译器需要检查所有可用的构造函数,包括私有的构造函数。

需要注意的是,这种情况只会影响到类的外部访问,类的成员函数和友元函数仍然可以访问私有构造函数。因此,如果你不希望在类的外部使用某个构造函数,可以将其声明为私有。这样,编译器在匹配函数时就不会考虑这个私有构造函数,从而避免了不必要的匹配错误。

页面内容是否对你有帮助?
有帮助
没帮助

相关·内容

为什么应该尽可能避免静态构造函数中初始化静态字段?

不同的是Foo以内联(inline)赋值的方法进行初始化,而Bar则将初始化操作定义静态构造函数中。...但是当我们调用一个并不涉及类型静态字段的Invoke方法时,定义Foo中的静态构造函数会自动执行,但是定义Bar中的则不会,由此可以看出一个类型的静态构造函数的执行时机与类型是否具有beforefieldinit...具体规则如下,这一个规则直接定义CLI标准ECMA-335中,静态构造函数在此标准中被称为类型初始化器(Type Initializer)或者.cctor。...: 第一次读取任何一个静态字段之前; 第一个执行任何一个静态方法之前; 引用类型:第一次调用构造函数之前; 值类型:第一次调用实例方法; 由于beforefieldinit标记只有没有显式定义静态构造函数的情况下才会被添加...四、关于“All-Zero”结构体 如果我们一个结构体中显式定义了一个静态构造函数,当我们调用其构造函数之前,静态构造函数会自动执行。

18410

C++基础(一).抽象

,只能通过内部定义的方法来进行修改和查看,所以要想修改和查看只能通过定义的公有方法来进行,这就达到了封装的效果 public: int add(); int sub(); int mul()...; int div(); //定义几个公有的方法,只有公有属性的变量或方法才能被外部引用 Calc(int x=1, int y=1); //与类名相同的成员函数构造函数构造函数是特殊的成员函数...,只要创建类类型的新对象,都要执行构造函数,一般而言构造函数的工作是保证每个对象的数据成员具有合适的初值,不能有返回值(和类型),因为要被调用,所以通常作为public成员,创建对象时自动调用 ~Calc...,不需要程序员显式调用(程序员也没法显式调用),而是销毁对象时自动执行,析构函数没有参数,不能被重载,因此一个类只能有一个析构函数,如果用户没有定义,编译器会自动生成一个默认的析构函数 void...公有属性 保护属性 成员变量 成员函数 构造函数 析构函数 特别是构造函数与析构函数的调用时间需要十分清楚 析构函数根据变量的生命周期,作用域,堆内申请和栈内申请的不同,触发的时机也不尽相同,需要对内存回收的时间有一定的认识才能准确判断

37710
  • 性能大杀器:c++中的copy elision

    ,创建一个临时对象并返回,此时会输出Default ctor•将上述的需要返回的临时对象以拷贝方式赋值给函数返回值,此时会输出Copy ctor•函数返回值作为obj1的拷贝对象,此时会输出Copy ctor...,此时会输出Copy ctor•函数返回值作为obj2的拷贝对象,此时会输出Copy ctor 对前面的输出做个简单总结,如下: Default ctor // CreateObj1中以Obj()方式创建临时变量...,将temp2值赋值给o2 在上一节中,我们提到过,可以通过使用移动构造的方式来避免拷贝,为了测试该功能,尝试Obj类中新增一个移动构造函数: #include struct...fno-elide-constructors): Default ctor Move ctor Move ctor Default ctor Move ctor Move ctor 看了上述输出,不禁奇怪,为什么...这意味着,当函数返回一个自动对象时,编译器可以优化掉不必要的拷贝或移动操作,直接将自动对象构造函数调用的返回对象中,以提高效率。这种优化 C++ 标准中被明确规定,以支持更高效的代码生成。

    14910

    重温 CC++ 笔记

    /gcc/Attribute-Syntax.html attribute 参数: constructor 构造器之前执行 destructor 析构后执行 cleanup static_assert...多重继承、纯虚接口类、虚析构函数,动态转型、对象切片、函数重载等很多危险的陷阱 C++ 用 : 表示继承,final 放在类名后面 C++ 四大函数: 构造函数 析构函数 拷贝构造函数 拷贝赋值函数...一般认为,重要的构造函数(普通构造、拷贝构造、赋值构造、转移构造)、析构函数,尽量声明为 noexcept,优化性能。 10 节 函数式编程 函数的目的:封装执行的细节,简化程序的复杂度。...www.zhihu.com/question/44865154 2 点: friend 友元函数可以访问私有方法 规定:重载一个二元的全局运算符,需要声明这个函数为友元 < 比较运算符是个“二元运算符”...【SalesData】 跟着敲一下 代码里显式声明了转移构造和转移赋值函数,这样,放入容器的时候就避免了拷贝,能提高运行效率。

    1.3K30

    大话 JavaScript(Speaking JavaScript):第十六章到第二十章

    正如我们刚才查看内置构造函数的实例时所看到的,用户未创建的所有内容都会被for-in隐藏。...本节将描述三种解决这个限制的技术: 构造函数环境中的私有数据 使用标记键属性中存储私有数据 使用具体键属性中存储私有数据 此外,我将解释如何通过 IIFE 保持全局数据私有。...私有值 存储环境中的数据和函数私有的——只能由构造函数和它创建的函数访问。 特权方法 私有函数可以访问公共属性,但原型中的公共方法无法访问私有数据。因此,我们需要特权方法——实例中的公共方法。...特权方法是公共的,可以被所有人调用,但它们也可以访问私有值,因为它们是构造函数中创建的。...使用具体化键属性中保持私有数据 私有属性的一个问题是,键可能会发生冲突(例如,来自构造函数的键与来自子构造函数的键,或来自混入的键与来自构造函数的键)。

    39620

    PHP之十六个魔术方法详解

    每个类中都有一个构造方法,如果没有显示地声明它,那么类中都会默认存在一个没有参数且内容为空的构造方法。...1、 构造方法的作用 通常构造方法被用来执行一些有用的初始化任务,如对成员属性创建对象时赋予初始值。...2、 构造方法的类中的声明格式 function __constrct([参数列表]){ 方法体 //通常用来对成员属性进行初始化赋值 } 3、 类中声明构造方法需要注意的事项 1、同一个类中只能声明一个构造方法...该方法调用的方法不存在时会自动调用,程序仍会继续执行下去。 请参考如下代码: <?...十六、__debugInfo(),打印所需调试信息 注意: 该方法PHP 5.6.0及其以上版本才可以用,如果你发现使用无效或者报错,请查看啊你的版本。 看代码: <?

    1.4K41

    C++特殊类设计+类型转换

    请设计一个类,只能在堆上创建对象 实现方式: 将类的构造函数私有,拷贝构造声明成私有。防止别人调用拷贝栈上生成对象。...请设计一个类,只能在栈上创建对象 方法一:同上将构造函数私有化,然后设计静态方法创建对象返回即可。...C++98 将拷贝构造函数与赋值运算符重载只声明不定义,并且将其访问权限设置为私有即可。 class CopyBan { // ......请设计一个类,不能被继承 C++98方式 // C++98中构造函数私有化,派生类中调不到基类的构造函数。...C语言中的类型转换 C语言中,如果赋值运算符左右两侧类型不同,或者形参与实参类型不匹配,或者返回值类型与接收返回值类型不一致时,就需要发生类型转化,C语言中总共有两种形式的类型转换:隐式类型转换和显式类型转换

    1.2K30

    【黄啊码】这篇文章告诉你php的魔术方法有多方便

    每个类中都有一个构造方法,如果没有显示地声明它,那么类中都会默认存在一个没有参数且内容为空的构造方法。     ...1、 构造方法的作用     通常构造方法被用来执行一些有用的初始化任务,如对成员属性创建对象时赋予初始值。     ...2、 构造方法的类中的声明格式 function __constrct([参数列表]){ 方法体 //通常用来对成员属性进行初始化赋值 }     3、 类中声明构造方法需要注意的事项 1...)、同一个类中只能声明一个构造方法,原因是,PHP不支持构造函数重载。...该方法调用的方法不存在时会自动调用,程序仍会继续执行下去。     请参考如下代码: <?

    88620

    【C++】42道面试经典问题总结

    1.定义类的时候,struct默认是公有的,class默认是私有的 2.继承时,如果不写明继承方式,class默认继承方式是私有继承,struct默认是公有继承 3.C++中struct空结构体是...局部变量存放stack上,通过ebp指针偏移-4来访问的,不会产生符号 拷贝构造函数为什么传引用不传值?...函数的调用开销 push ebp压入实参 mov ebp esp sub esp 4Ch开辟栈帧 rep stos 0×CCCCCCCC(Windows) 注意在GCCgcc/g++下不会做初始化操作...派生类的初始化过程是:基类构造然后是派生类构造。所以可以把基类的构造函数私有化 什么是纯虚函数为什么要有纯虚函数?虚函数表放在哪里?...虚函数的调用前提是对象存在, 一个派生类的构造要先调用基类构造函数,如果基类是虚构造函数则会无限循环 构造函数中,是不会进行动态绑定的,虚构造函数本身也不能实现成虚函数

    9210

    【C++】类与对象理解和学习(下)

    explicit关键字 隐式类型转换 我们知道,进行赋值操作时,假如两边类型不匹配,我们会用()进行强制类型转换,比如int a=(int)1.1,我们将浮点型数据强制转换为了整型数据,这种...我们会发现编译器并没有调用拷贝构造,这是为什么呢?这是由于我们的编译器对此进行了优化,直接将构造+拷贝构造优化为直接构造。...如下: 不过这种隐式类型转换的代码可读性太差了,为了限制自定义类型对象的这种行为,我们可以使用关键字explicit,我们构造函数前面加上explicit,就会禁止这种隐式类型转换行为。...友元函数与友元类 友元函数 友元函数可以 直接访问类的 私有成员,它是 定义类外部的 普通函数,不属于任何类,但需要在类的内部声明,声明时需要加 friend关键字。...不具有继承性(后面讲到继承时会提) 友元类 与友元函数相通,这里我们将一个类的声明放在另一个类中,并在前面加上friend关键字,就会变成这个类的友元类。

    49230

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

    构造函数优先匹配。...5.0}; // 使用花括号初始化,调用第二个构造函数 最后使用空参数{}初始化时,会匹配默认构造函数,只有传入{}才会匹配initializer_list构造函数。...构造重载匹配中,只要参数能够强转std::initializer_list的T,就会匹配std::initializer_list构造函数,即便有更加匹配构造函数。...优先考虑使用deleted函数而非使用未定义的私有声明 阻止类的某些特定成员函数被外部调用时,有两种常见的方法:使用 private 访问修饰符将其声明为私有,或者使用 delete 关键字将其声明为已删除...让const成员函数线程安全 const成员函数意味着只读,因此这种函数使用时会被默认为线程安全。但在实际编码中,实现的const成员函数可能存在线程不安全的情况。

    19220

    Java 学习笔记(7)——接口与多态

    类中存在虚函数时,对象会有一个虚函数表的头指针,虚函数表会存储虚函数的地址,使用父类的指针或者引用来调用方法时会根据虚函数表中的函数地址来调用函数,会形成多态。...类类型转化 上面的println 函数,它需要传入的是Object类的引用,但是调用该方法时,从来都没有进行过类型转化,都是直接传的,这里是需要进行类型转化的,由子类转到父类的时候,Java进行了隐式类型转化...抽象方法是不需要写实现的方法,它只需提供一个函数的原型。而抽象类不能创建实例,必须有派生类重写抽象方法。为什么抽象类不能创建对象呢?...使用抽象类需要注意下面几点: 不能直接创建抽象类的对象,必须使用实现类来创建对象 实现类必须实现抽象类的所有抽象方法,否则该实现类也必须是抽象类 抽象类可以有自己的构造方法,该方法仅供子类构造时使用 抽象类可以没有抽象方法...接口中的静态方法 从Java 8中开始,允许接口中定义静态方法,静态方法可以使用实现类的对象进行调用,也可以使用接口名直接调用 接口中的私有方法 从Java 9开始运行在接口中定义私有方法,私有方法可以解决默认方法中存在大量重复代码的情况

    76940

    一个C++bug引入的许多知识

    接着我们把temp放进了vector中,这个时候会调用car的拷贝构造函数,由于car没有定义自己的拷贝构造函数,因此将会执行默认的拷贝构造函数进行浅拷贝操作 这个时候的内存是这个样子 ?...那么这又是为什么C++中,堆内存是存在复用的可能的,如果上一个内存已经被释放调,new新对象的时候,新对象的内存便可能建立刚刚释放的内存上 我们知道vector内部是类似数组的连续的储存空间...vector发现空间不足时,会在其他地方重新申请一块内存空间,调用原来对象的拷贝构造函数 新的地方进行创建,并把原来地方的对象析构调 第一次循环的时候 vector的大小是1,容量也是1,第二次调用...这样当程序结束调用析构函数的时候,由于vcar[0]和vcar[1]中_car指向同一块内存,delete时就会出现问题 问题的根源依旧是没有深拷贝构造函数 四、结论 1、赋值函数,拷贝构造函数,析构函数通常应该被视为一个整体...,这期间会调用元素的析构函数和拷贝构造函数 3、C++中堆内存是可以复用的,当你释放一块内存之后,又立即申请一块内存,新申请的内存空间很可能在刚刚释放的内存上

    1.2K90

    Canary保护机制及绕过

    Canary基本介绍 基本的栈溢出中,我们可以通过没有限制输入长度或限制不严格的函数等向栈中写入我们构造的数据,可写入的数据包括但不限于: 一段可执行的代码(关闭NX防护的前提下) 一段特意构造的返回地址等...传统的防御机制之一就是开启 Canary防护,该机制会向我们运行程序的栈底放入一串8字节的随机数据,函数即将返回时会验证该数据是否发生改变,若发生改变则说明栈被改变了,直接call进__stack_chk_fail...OBJS=pwn_1.c CC=gcc # 默认就为gcc CFLAGS+=-fstack-protector -no-pie -g pwn_1:$(OBJS) $(CC) $^ $(CFLAGS...) -o $@ clean: $(RM) *.o # 可不加 之后直接make即可,记得将源文件命名为pwn_1.c,之后gcc可能会提示报错提示read函数可能存在溢出的可能,不用理会...objdump 通过观察代码可以多看到我们代码中是有一个等待被我们利用的函数backdoor()的,所以我们的目的实际上就是main函数执行完毕之后返回到该函数中,那我们势必就要计算出该函数与main

    82910

    58龙哥教你“如何做系统性能优化”(纯干货)

    (5)Register parameters(寄存器参数) (6)Lazy computation(延时计算) 最近不用的变量,不要急着去初始化(意味着可能执行复杂的构造),如果某个分支跳出了函数,这些动作就浪费了...(8)Inline(内联函数) (9)Macro(宏定义) (10)Allocation on stack(局部变量) 避免栈上申请大数组,其初始化和销毁的代价很高。...工具能解决的问题: (1)建立性能基线,以作对比; (2)帮助定位性能瓶颈; (3)帮助验证优化方案; 性能测试工具一般由这么几种: (1)收集CPU的性能计数; (2)利用编译器的功能,函数入口和出口加回调函数...这两个工具都需要重新编译代码,它们都用到了gcc里面的finstrument-functions选项。编译时会函数入口,出口加回调函数,而且inline函数也会改成非inline的。...Cache为什么有效?避免已计算过的开销,获取更快的访问。 Cache的难点在哪里?一是快速匹配;二是Cache容量有效,需要较好的替换策略; Cache在哪些情况下有效?时间局部性。

    1.3K41

    龙神教你“如何做系统性能优化”

    (5)Register parameters(寄存器参数) (6)Lazy computation(延时计算) 最近不用的变量,不要急着去初始化(意味着可能执行复杂的构造),如果某个分支跳出了函数,这些动作就浪费了...(8)Inline(内联函数) (9)Macro(宏定义) (10)Allocation on stack(局部变量) 避免栈上申请大数组,其初始化和销毁的代价很高。...工具能解决的问题: (1)建立性能基线,以作对比; (2)帮助定位性能瓶颈; (3)帮助验证优化方案; 性能测试工具一般由这么几种: (1)收集CPU的性能计数; (2)利用编译器的功能,函数入口和出口加回调函数...这两个工具都需要重新编译代码,它们都用到了gcc里面的finstrument-functions选项。编译时会函数入口,出口加回调函数,而且inline函数也会改成非inline的。...Cache为什么有效?避免已计算过的开销,获取更快的访问。 Cache的难点在哪里?一是快速匹配;二是Cache容量有效,需要较好的替换策略; Cache在哪些情况下有效?时间局部性。

    96170

    【C++入门篇】保姆级教程篇【中】

    ,快速变换的业务与需求对高速发展的硬件已经不匹配了,于是祖师爷设计C++时也引入了面向对象这一特性。...实际上,与构造函数功能相反,析构函数不是完成对象本身的销毁,局部对象销毁工作是由 编译器完成的。而对象销毁时会 自动调用 析构函数,完成对象中的开辟的内存销毁工作。...可以看到,这里编译器直接指定了你拷贝构造形参写错了,这是为什么?...其实这样是会发生无穷递归的,我们知道类的对象进行传值传递时会自动调用拷贝构造,但是如果拷贝构造也是形参,那么传值传递就会引发对象的拷贝,一直循环发生无穷递归。...,首次函数传参的时候,函数结束时会调用一次析构函数,但是问题是这里拷贝的指针和原类的成员指针指向的是同一片空间,所以函数结束时调用析构会销毁这片空间,原对象生命周期结束时又会调用一次析构函数,但是原来已经给指针是放过一次了

    7410

    C++设计模式-单例模式讲解

    单例模式的基本特点: 私有构造函数:防止其他对象通过构造函数创建该类的实例。 静态成员函数:提供一个全局访问点用于返回该类的唯一实例。 静态成员变量:保存该类的唯一实例。...实现步骤: 声明单例类:定义类并将其构造函数相关设置为私有,这是为了防止产生多个单例 创建静态成员变量:声明一个静态成员变量来存储唯一的实例。...很明显只有第一次请求时会创造并初始化单例实例,另外记得类外定义类内声明的静态成员变量 非线程安全的简单使用例: #include class Singleton { public:...~Singleton() {} // 私有析构函数 Singleton(const Singleton&) = delete; // 删除拷贝构造函数 Singleton& operator=(...\n"; } private: Singleton() {} // 私有构造函数 ~Singleton() {} // 私有析构函数 Singleton(const Singleton

    23730
    领券