C++ 从基类调用派生类的隐藏(非虚拟)方法

C++ 从基类调用派生类的隐藏(非虚拟)方法,c++,inheritance,compile-time,member-hiding,C++,Inheritance,Compile Time,Member Hiding,是否有一种方法(模板、宏或其他)来替代在编译时从公共方法派生的对隐藏在中的调用,以便派生调用的实例是自己的隐藏在中派生的(,而不将隐藏在中的派生在基中) #包括 阶级基础{ 公众: void common(){ //对其他方法的一些调用 隐藏在_派生()中的_; //然而,对其他方法的一些调用 } void隐藏在_派生()中的_{ std::cout将其虚拟化,然后您甚至可以使用基类ptr: 或者就像你对一个物体所做的那样: 将其虚拟化,然后您甚至可以使用基类ptr: 或者就像你对一个物体所做的

是否有一种方法(模板、宏或其他)来替代在编译时从公共方法派生的对隐藏在中的调用,以便派生调用的实例是自己的隐藏在中派生的(,而不将隐藏在中的派生在基中)

#包括
阶级基础{
公众:
void common(){
//对其他方法的一些调用
隐藏在_派生()中的_;
//然而,对其他方法的一些调用
}
void隐藏在_派生()中的_{

std::cout将其虚拟化,然后您甚至可以使用基类ptr:

或者就像你对一个物体所做的那样:

将其虚拟化,然后您甚至可以使用基类ptr:

或者就像你对一个物体所做的那样:

不将其虚拟化-好吧,这就是虚拟函数的全部要点。您需要解决的实际问题是什么?为什么您不能将
隐藏在派生中的
虚拟化?如果
隐藏在派生中()
不是
基的
虚拟
函数,那么
基::公共()
需要手动计算出对象的实际类型
。除非
Base
包含为每个派生类和
Base::common()的实现唯一设置的一些信息,否则这是不可能的
包含关于每个可能派生类的信息,并在派生新类时更新。这样做的成本(以及由于忘记正确更新
Base::common()
而导致错误的可能性)意味着在派生()中隐藏
会更容易
virtual。您是否需要派生类来实际共享一个公共基?如果不需要,CRTP可能会工作。示例:我的示例中没有每个基都是唯一的基,因此Derived1和Derived2将具有不同的基。如果不使其虚拟化,那么这就是虚拟函数的全部要点。您需要解决的实际问题是什么?为什么不能您将
隐藏在\u-derived中
虚拟?如果
隐藏在\u-derived()中
不是
Base
虚拟函数,则
Base::common()
需要手动计算出对象的实际类型
。除非
Base
包含为每个派生类和
Base::common()的实现唯一设置的一些信息,否则这是不可能的
包含关于每个可能派生类的信息,并在派生新类时更新。这样做的成本(以及由于忘记正确更新
Base::common()
而导致错误的可能性)意味着在派生()中隐藏
会更容易
virtual。您是否需要派生类来实际共享一个公共基?如果不需要,CRTP可能会起作用。示例:我的示例中的每个基都是唯一的基,因此Derived1和Derived2将具有不同的基。您可以使用function ptr或std::function,并在构建对象期间将其与lambda一起分配。派生是在Bas之后构建的所以它应该总是调用“最派生的”实现
在基类中是虚拟的,对吗?在问题的注释中有一个CRTP模式。它似乎做了我需要的事情。wandbox.org/permlink/SCPmaQ4g5PoQzPRi看起来很有趣。我不知道lambda内部是如何工作的。这样做不会有任何额外的运行时开销(类似于虚拟方法)?Lambda与使用调用Lambda主体的
操作符()创建struct相同。传递指向此的指针后,没有使用虚拟方法。请查看此处以测试它:@psb Lambda本身与普通方法调用一样便宜(编译器可以内联它,因为它知道一切)但是,
std::function
在内部执行类型擦除,这肯定涉及虚拟方法调用。用
std::function
替换虚拟方法是毫无意义的,几乎肯定会导致性能下降(好的编译器可能会设法内联完成所有的
std::function
抽象,但在这种情况下,他们可能会首先对虚拟方法进行同样的操作。是的,您正在过早地优化-分析您的方法,然后再决定。)您可以使用function ptr或std::function,并在构建对象期间为其分配lambda。派生是在Base之后构建的,因此它应该始终调用“最派生”的实现。
但隐藏在派生()中
在基类中是虚拟的,对吗?在问题的注释中有一个CRTP模式。它似乎做了我需要的事情。wandbox.org/permlink/SCPmaQ4g5PoQzPRi看起来很有趣。我不知道lambda内部是如何工作的。这样做不会有任何额外的运行时开销(类似于虚拟方法)?Lambda与使用调用Lambda主体的
操作符()创建struct相同。传递指向此的指针后,没有使用虚拟方法。请查看此处以测试它:@psb Lambda本身与普通方法调用一样便宜(编译器可以内联它,因为它知道一切)但是,
std::function
在内部执行类型擦除,这肯定涉及虚拟方法调用。用
std::function
替换虚拟方法是毫无意义的,几乎肯定会导致性能下降(好的编译器可能会设法内联完成所有的
std::function
抽象,但在这种情况下,他们可能会首先对虚拟方法进行同样的操作。是的,您正在过早地优化-分析您的方法,然后再决定。)
#include <iostream>

class Base {
public:
    void common() {
        // some calls to other methods
        hidden_in_derived();
        // yet some calls to other methods
    }

    void hidden_in_derived() {
        std::cout << "A" << std::endl;
    }
};

class Derived : public Base {
public:
    void hidden_in_derived() {
        std::cout << "B" << std::endl;
    }
};


int main() {
    Derived d;
    d.common(); // want hidden_in_derived (prints "B") here somehow ?

}