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

成员函数指针作为模板论证在继承的成员函数上失败,原因和原因是什么?

成员函数指针作为模板论证在继承的成员函数上失败的原因是,继承会导致派生类的成员函数和基类的成员函数在内存中的布局发生变化,从而导致成员函数指针的类型不匹配。

在C++中,成员函数指针的类型包括成员函数的返回类型、参数列表以及const和volatile限定符。当基类和派生类之间存在继承关系时,派生类的成员函数会继承基类的成员函数,但它们在内存中的布局可能会发生变化,特别是在多重继承和虚拟继承的情况下。

由于派生类的成员函数和基类的成员函数在内存中的布局可能不同,成员函数指针的类型也会不同。如果将基类的成员函数指针赋值给派生类的成员函数指针,或者将派生类的成员函数指针作为模板参数传递给模板函数,就会导致类型不匹配的错误。

为了解决这个问题,可以使用虚函数和虚函数指针来实现多态性,而不是使用成员函数指针。虚函数通过动态绑定的方式,在运行时确定调用的函数,可以正确处理继承关系。另外,可以使用函数对象(Functor)或Lambda表达式来替代成员函数指针,因为它们可以在编译时进行类型推断,避免了类型不匹配的问题。

总结起来,成员函数指针作为模板论证在继承的成员函数上失败的原因是继承导致派生类的成员函数和基类的成员函数在内存中的布局发生变化,从而导致成员函数指针的类型不匹配。为了解决这个问题,可以使用虚函数、虚函数指针、函数对象或Lambda表达式来实现多态性。

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

相关·内容

【笔记】《Effective C++》条款26-55

deque, 只是依据deque上而已) 39 明智而审慎地使用private继承 由于访问限制原因, 编译器无法自动将private继承派生类转型为基类, 且派生类无法使用基类成员 因此private...这个规矩也就是Java等语言中对接口这种多重继承性质类有特殊设计原因 当用到这种虚基类作为接口时, 一般都采用公有继承, 因为其没有实际变量, 那么各种接口函数都应该是设计给用户使用 7 模板与泛型编程..., 因此我们无法直接在模板类中调用模板基类成员 有三种方法处理这个问题: 调用基类函数前加上this指针this->foo();, 用指针进行多态调用 用using声明式using Base<Tmp...45 运用成员函数模板接受所有兼容类型 模板之间并没有什么类似继承关系固有关系, 无法自动继承类之间进行隐式转换, 智能指针类通过底层转型来模拟这种关系 方法是编写用于指针间类型转换构造模板,...称为成员函数模板(member function template) 智能指针类编写了非explicit构造函数, 自身底层是T类型指针时, 接受一个U类型指针作为构造函数参数, 然后通过原始指针本身转换继承形式将

92830

C++心决之类对象详解(上篇)(封装入门篇)

【访问限定符说明】 1. public修饰成员类外可以直接被访问 2. protectedprivate修饰成员类外不能直接被访问(此处protectedprivate是类似的) 3...】 问题: C++ 中 struct class 区别是什么?...注意:继承模板参数列表位置,structclass也有区别 4.2 封装 【面试题】 面向对象三大特性: 封装、继承、多态 。...C++ 中通过引入 this 指针解决该问题,即: C++ 编译器给每个 “ 非静态成员函数 “ 增加了一个隐藏 指针参数,让该指针指向当前对象 ( 函数运行时调用该函数对象 ) ,函数体中所有...只能在“成员函数内部使用 3. this指针本质上是“成员函数形参,当对象调用成员函数时,将对象地址作为实参传递给 this形参。所以对象中不存储this指针

15910
  • 【C++进阶】多态理解

    一.多态是什么 多态是不同继承关系类对象,去调用同一函数,产生了不同行为。 对于多态,不同对象传过去,会调用不同函数; 即多态调用看是指向对象。...,例如:函数重载模板;         2.动态绑定,也称为动态多态,是程序运行阶段确定,根据具体拿到类型确定程序               具体行为,调用具体函数。...接口继承实现继承 实现继承:普通函数继承是一种实现继承; 接口继承:虚函数继承是一种接口继承,如果不实现多态,不要把函数定义成虚函数。...虚函数与静态成员函数 静态成员函数没有this指针,使用类型::成员函数调用方式无法访问虚函数表,所以静态成员函数无法放进虚函数表,即静态成员函数不能设置成虚函数。...结论 析构函数建议设置成虚函数,因为有时可能利用多态方式通过基类指针调用子类析构        数,尤其是父类析构函数强力建议设置为虚函数,这样动态释放父类指针所指子类      对象时,能够达到析构多态

    11710

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

    HelloWorld 124、模板模板函数区别是什么?...函数模板实例化是由编译程序处理函数调用时自动完成,而类模板实例化必须由程序员程序中显式地指定。即函数模板允许隐式调用显式调用而类模板只能显示调用。...,下标运算符通常以所访问元素引用作为返回值,同时最好定义下标运算符常量版本非常量版本; 7、 箭头运算符必须是类成员,解引用通常也是类成员;重载箭头运算符必须返回类指针; 129、当程序中有函数重载时...所以为了容易使用,几乎总是头文件中放置全部模板声明定义。 140、成员函数中调用delete this会出现什么问题?对象还可以使用吗?...1、类对象内存空间中,只有数据成员函数指针,并不包含代码内容,类成员函数单独放在代码段中。调用成员函数时,隐含传递一个this指针,让成员函数知道当前是哪个对象调用它。

    2.2K30

    大厂面试经历(附100+面试题干货)

    Dynamic_cast:针对基类派生类指针引用转换,基类派生类之间必须要继承关系,是安全    Reinterpret_cast:允许将任何指针类型转为其他指针类型,是安全  8:Malloc...实现:需要注意申请失败,如果相应处理函数则调用,否则抛出bad_alloc异常  40:如何得到一个结构体内成员偏移量? 41:进程与线程区别?  ...不可以为虚函数,因为调用构造函数时,虚表指针并没有在对象内存空间中,必须要构造函数调用完成后才会形成虚表指针。    拷贝构造函数是构造函数所以理由同上。  44:析构函数能不能虚函数?...原因:多文件处理变为一个文件其实是通过链接器来实现,所以如果用源文件来处理模板实现,会导致链接失效,最主要原因还是在编译,编译器会暂时不处理模板类只有实例化对象时才去处理,但是这就需要实现代码了...对于有虚函数虚表存在类,进行memset后不能调用虚函数虚基表继承而来数据函数  50:对一个数组而言,delete adelete[] a有什么区别?为什么?

    1.3K20

    知识总结:C++工程师106道面试题总结(含答案详解)

    Dynamic_cast:针对基类派生类指针引用转换,基类派生类之间必须要继承关系,是安全    Reinterpret_cast:允许将任何指针类型转为其他指针类型,是安全  Malloc...实现:需要注意申请失败,如果相应处理函数则调用,否则抛出bad_alloc异常  如何得到一个结构体内成员偏移量? ? 进程与线程区别?  ...不可以为虚函数,因为调用构造函数时,虚表指针并没有在对象内存空间中,必须要构造函数调用完成后才会形成虚表指针。    拷贝构造函数是构造函数所以理由同上。  析构函数能不能虚函数?...原因:多文件处理变为一个文件其实是通过链接器来实现,所以如果用源文件来处理模板实现,会导致链接失效,最主要原因还是在编译,编译器会暂时不处理模板类只有实例化对象时才去处理,但是这就需要实现代码了...对于有虚函数虚表存在类,进行memset后不能调用虚函数虚基表继承而来数据函数  对一个数组而言,delete adelete[] a有什么区别?为什么?

    2.6K90

    【C++】侯捷C++面向对象高级编程(下)

    ---- 成员模板(member template) 也就是模板嵌套,模板中有模板。 如下图黄色部分。 说明: 黄色这一块是当前模板一个成员,同时它自己也是个模板。...所以它就叫做成员模板。 T1,T2可以变化,U1,U2也可以变化。 STL标准库中会大量出现成员模板,先来一个小示例: 解释: 鲫鱼类继承自鱼类,麻雀类继承自鸟类。...调用指针->向上转型(转为具体子类)->调用虚函数 补充: 继承父类,函数继承是调用权。 父类函数子类也一定要有。 父类子类中可以出现同名函数,但实际上不是同一个。...---- this pointer 类成员函数中,默认会有一个this指针传递进来。由编译器自己处理。...常量对象不能调用非常量成员函数,反之,可以。 但是,当成员函数const版本非const版本都存在,则常量对象只能调用const版本,非const对象只能调用非const版本。

    67420

    C++ 类使用规范建议

    缺点:构造函数中执行操作引起问题有: (1) 构造函数中不易报告错误,尽量不要使用异常,原因是因为构造函数中抛出异常,概念上将被视为该对象没有被成功构造,因此当前对象析构函数就不会被调用,那么就容易造成内存泄露...将类作为STL容器值得时候,你可能有使类可拷贝冲动。类似情况下,真正该做是使用指针指向STL容器中对象,可以考虑使用std::tr1::shared_ptr。...使用继承相关规范: (1)所有继承尽量使用public,如果想私有继承的话,应该采取包含基类实例作为成员方式作为替代。 (2)不要过多使用实现继承,组合通常更合适一些。...(3)基类如果有虚函数函数,那么令析构函数为virtual。原因是保证通过基类指针能够动态调用子类析构函数,避免内存泄露。...定义:多重继承允许子类拥有多个基类,要将作为纯接口基类具有实现基类区别开来。 优点:相比单继承,多重实现继承可令你重用更多代码。

    1.8K20

    深入理解面向对象编程特性 : 继承

    原因在于protected或private继承成员只能在子类内部使用,限制了代码扩展性可维护性。...但是由于foo()是依赖于模板参数T成员函数,编译器无法确定foo()是从基类继承。这是因为模板是按需实例化,编译器第一次查找时并不知道派生类实例化时会包含哪些基类成员。...使用Derived d;初始化时候会对构造函数进行实例化并调用构造函数,但是当使用d.bar();时,如果在bar()中为foo();即会编译错误,原因就如上述,无法确定从基类继承。...此时AB类构成是隐藏关系。 编译运⾏结果是什么? 编译报错。(b.fun(); ) ⼦类默认成员函数 子类构造函数 子类构造函数必须调用父类构造函数来初始化父类那部分成员。...原因是友元关系不继承:Display函数虽然是Person友元,但它不是Student友元,所以不能访问Student保护成员

    10310

    面试常考知识点总结——面试必看

    模板static函数只可被这一模块内其他函数调用,这个函数适用范围被限制声明他模板类中static成员变量属于整个类所拥有,对象所有对象只有一份复制 类中static成员函数属于整个类所拥有...,这个函数不接收this指针,因而只能访问类static成员变量 引用指针有什么区别?...平衡树(BT) 指的是,任意节点子树高度差都小于等于1。 堆栈溢出一般是什么原因导致函数调用层次太深。...普通函数:普通函数不属于成员函数,是不能被继承。普通函数只能被重载,不能被重写,因此声明为虚函数没有意义。 友元函数:友元函数不属于类成员函数,不能被继承。...内联成员函数:内联函数是在编译时展开,而虚函数是为了实现多态,是在运行时绑定。因此内联函数多态特性相违背。 静态成员函数:首先静态成员函数理论是可继承

    84720

    Google C++编程风格指南(四)之类相关规范

    将类作为STL容器值得时候,你可能有使类可拷贝冲动。类似情况下,真正该做是使用指针指向STL容器中对象,可以考虑使用std::tr1::shared_ptr。...使用继承相关规范: (1)所有继承尽量使用public,如果想私有继承的话,应该采取包含基类实例作为成员方式作为替代。 (2)不要过多使用实现继承,组合通常更合适一些。...(3)基类如果有虚函数函数,那么令析构函数为virtual。原因是保证通过基类指针能够动态调用子类析构函数,避免内存泄露。...定义:多重继承允许子类拥有多个基类,要将作为纯接口基类具有实现基类区别开来。 优点:相比单继承,多重实现继承可令你重用更多代码。...尤其是不要仅仅为了STL容器中作为key使用就重载operator==或operator<,取而代之,你应该在声明容器时候,创建相等判断大小比较仿函数类型。

    87421

    程序员必须掌握600个英语单词

    )运算子调用操作符 (同 function call operator) candidate function 候选式 候选函数式多载决议程序中出现候选式) chain 串链(例...功能 function template 模板式范本 函数模板 functor 仿式 仿式、子 game 游戏 游戏 generate 生成 generic 泛型、一般化 一般化...功能 function template 模板式范本 函数模板 functor 仿式 仿式、子 game 游戏 游戏 generate 生成 generic 泛型、一般化 一般化...机制 机制 member 成员 成员 member access operator 成员取用运算子(有 dot arrow 两种) 成员存取操作符 member function 成员式...C++ Primer 3/e, 15.8.2 platform 平台 平台 pointer 指标 指针 址位器(址叁器 reference 形成对映,满好) poll 轮询 轮询 polymorphism

    1.3K20

    程序员应该掌握600个英语单词

    )运算子调用操作符  (同 function call operator)  candidate function 候选式 候选函数  (式多载决议程序中出现候选式)  chain 串链(例...功能  function template 模板式范本 函数模板  functor 仿式 仿式、子  game 游戏 游戏  generate 生成  generic 泛型、一般化 一般化...功能  function template 模板式范本 函数模板  functor 仿式 仿式、子  game 游戏 游戏  generate 生成  generic 泛型、一般化 一般化...机制 机制  member 成员 成员  member access operator 成员取用运算子(有 dot arrow 两种) 成员存取操作符  member function 成员式...C++ Primer 3/e, 15.8.2  platform 平台 平台  pointer 指标 指针  址位器(址叁器 reference 形成对映,满好)  poll 轮询 轮询  polymorphism

    1.3K00

    《Effective C++》学习笔记

    继承体系(注意虚函数) 支持类型转换(显示转换、类型转换操作符) 成员函数成员变量可见范围(public/protected/private) 是否用模板就能实现?...用tr1::function成员变量替换虚函数,从而允许包括函数指针在内任何可调用物搭配一个兼容于需求签名式。 将虚函数也做成另一个继承体系类,然后调用其类中添加一个指针来指向其对象。...条款36:绝不重新定义继承而来非虚函数 不要重新定义继承而来非虚函数,理论上,非虚函数意义就在于父类子类函数上保持一致实现。...如果是 is-a 关系,可以用继承,但如果是 has-a 关系,应该将一个类作为另一个类成员变量来使用,以利用该类能力,而不是去以继承方式使用。...条款45:运用成员函数模板接受所有兼容类型 真实指针允许父类指针指向子类对象,如果想要让自制智能指针也支持这种对象转换,那就需要特殊操作,因为一般模板类(智能指针能指向多种对象,必然是模板类)只能以自身模板声明类型来构造

    1.1K20

    【学习C++篇】 继承

    1.继承概念及定义 1.1继承概念 继承(inheritance)机制是⾯向对象程序设计使代码可以复⽤最重要⼿段,它允许我们保持原有类特性基础上进⾏扩展,增加⽅法(成员函数)属性(成员变量...当然他们也有⼀些不同成员变量函数,⽐如⽼师独有成员变量是职称,学⽣独有成员变量是学号;学⽣独有成员函数是学习,⽼师独有成员函数是授课。...(因为翻译原因,所以既叫基类/派⽣类,也叫⽗类/⼦类) 1.2.2 继承基类成员访问⽅式变化 总之,就是取权限最小那个。...1.3 继承模板 2. 基类派⽣类间转换 1. public继承派⽣类对象 可以赋值给 基类指针 / 基类引⽤。这⾥有个形象说法叫切⽚或者切割。...(派⽣类成员函数中,可以使⽤ 基类::基类成员 显⽰访问) 3. 需要注意是如果是成员函数隐藏,只需要函数名相同就构成隐藏。 4. 注意在实际中继承体系⾥⾯最好不要定义同名成员

    000

    UE4智能指针 TSharedPtr

    ,内存管理,虚函数使用等),就只占2倍(16字节)普通指针内存,更符合UE4命名规范,内部实现是不抛异常,不依赖任何第三方库,更容易调试等原因,那么下面就来看怎么实现。...为了解释这个原因,先看看DestroyObject里面做了什么: 可以看到,调用了模板传入参数DeleterType,并把Object作为参数传了进去。这个Deleter到底是什么呢?...这个CustomDeleter就是智能指针其中一个构造函数上指定。 这样,智能指针除了支持管理本身C++对象,用完自动delete这样对象,还可以支持一些不是通过delete来释放对象。...为什么要特意搞一个这样类呢?可以想象一下,如果一个对象被外部某个TSharedPtr管理,自己成员函数内,怎样获取外部这个智能指针呢?...这是因为并不是所有用智能指针类都继承了TSharedFromThis,为了保证只有继承类生效,通过中转一层可以用模板多态区分开。

    2.5K20

    【C++航海王:追寻罗杰编程之路】类与对象你学会了吗?(上)

    函数中按照顺序调用这些函数来完成整个做饭过程。在这种方式下,我们需要手动管理各个步骤之间数据传递调用顺序。...注意:继承模板参数列表位置,structclass也有区别。 4.2 -> 封装 面向对象三大特性:封装、继承、多态。 对象阶段,主要是研究类封装特性,那么什么是封装呢?...: Date类中有 Init 与 Print 两个成员函数函数体中没有关于不同对象区分,那当d1调用 Init 数时,该函数是如何知道应该设置d1对象,而不是设置d2对象呢?...C++中通过引入this指针解决该问题,即:C++编译器给每个“非静态成员函数“增加了一个隐藏 指针参数,让该指针指向当前对象(函数运行时调用该函数对象),函数体中所有“成员变量”...8.2 -> this指针特性 this指针类型:类类型* const,即成员函数中,不能给this指针赋值; 只能在“成员函数内部使用; this指针本质上是“成员函数形参,当对象调用成员函数

    7810

    访问私有成员——从技术实现角度破坏封装 性

    大约是大二上半学期时候接触C语言,在下半学期开始接触C++语言。C++教材前几章就介绍了其特性,即:C++是一门面向对象语言,具有封装、继承多态三个特点。...本着大方向不变原则,依然使用模板方式访问私有成员,而对于上节中提示非法访问私有成员,我也采用将对应函数声明为friend方式。...2、以&A::data_作为模板参数,对类模板PtrTaker进行显示实例化,显示实例化时候,虽然不创建对象,但是对于其中存在静态变量依然会进行初始化。...使用对象访问成员时候,其地址实际上分为两部分,以a.data_为例(此处忽略访问控制权限),一部分是athis指针,另一部分是data_成员A结构里偏移量,这个偏移量存储&A::data_...问题解决了,我却不知道原因 揭开lambda神秘面纱 多态实现-虚函数函数指针以及变体 【Modern C++】深入理解移动语义 【Modern C++】深入理解左值、右值 智能指针-使用、避坑实现

    23830

    嵌入式软件工程师笔试面试指南-CC++

    另外,class还可以定义模板类形参,比如template。 C++类内可以定义引用数据成员吗? 可以,必须通过成员函数初始化列表初始化。 面向对象与泛型编程是什么?...派生类构造函数中,编译器会加入构造基类代码,如果基类构造函数用到参数,则派生类在其构造初始化列表中必须为基类给出参数,就是这个原因。...如果成员类型是没有默认构造函数类,也只能使用初始化列表。若没有提供显式初始化时,则编译器隐式使用成员类型默认构造函数,此时编译器尝试使用默认构造函数将会失败成员变量初始化顺序是什么?...首先想到C++ 中,子类构造函数会自动调用父类构造函数。同样,子类析构函数也会自动调用父类析构函数。要想一个类不能被继承,我们只要把它构造函数析构 数都定义为私有函数。...由此可以看出,基类所有成员对子类对象都是不可见。 私有继承 私有继承特点是,基类公有成员保护成员作为派生类私有成员,并且不能被这个派生类子类所访问。 C++提供默认参数函数吗?

    1.6K11

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

    继承属于类类之间关系(除了继承还有组合) 继承是 a kind of关系 一种 组合是 a part of关系 一部分 继承好处: 代码复用 通过继承基类里面给所有派生类可以保留统一纯虚函数接口...,等待派生类进行重写,通过使用多态,可以通过基类指针访问不同派生类对象同名覆盖方法(做到开闭原则) 讲一下C++ 继承多态 多态:静态多态动态多态,静态多态是指编译时期多态,比如函数重载模板...动态多态是指运行时期多态,比如虚函数通过基类指针/引用指向派生类对象 C++ 空间配置器是什么?...可以指定对象成员变量初始化方式,尤其是指定成员对象构造方式 (初始化先后顺序与定义顺序有关,与初始化列表里出现顺序无关) CC++区别?CC++内存分布有什么区别?...++支持模板,泛型编程 6.C++有类对象,是OOP语言,可以采用很多设计模式 7.C++支持STL标准模板库,使解决问题更加方便 8.C++有异常机制、智能指针、运算符重载(使对象运算表现内置类型一样

    9210
    领券