简体   繁体   English

c++中是否存在“半纯”虚拟function?

[英]is there a "semi-pure" virtual function in c++?

Is there a way to write an abstract base class that looks like it's forcing an implementer to choose among a myriad of pure virtual functions?有没有办法编写一个抽象的基础 class 看起来它迫使实现者在无数纯虚函数中进行选择?

The abstract base classes I'm writing define a mathematically tedious function, and request that the deriving code define only building block functions.我正在编写的抽象基类定义了一个数学上乏味的 function,并要求派生代码只定义构建块函数。 The building block functions can be generalized to take on more arguments, though.不过,构建块功能可以推广到更多的 arguments。 For example, in the code below, it might "make sense" to allow another_derived::first() to take three arguments.例如,在下面的代码中,允许another_derived::first()获取三个 arguments 可能“有意义”。 The "mathematically tedious" part of this is the multiplication by 3 .其中“数学上乏味”的部分是乘以3 Unsurprisingly, it won't allow won't compile unless I comment out the creation of d2 .不出所料,除非我注释掉d2的创建,否则不会编译。 I understand why.我明白为什么。

One option is to create different base classes.一种选择是创建不同的基类。 One would request a single parameter function to be defined, and the other would request a two parameter function to be defined.一个请求定义单个参数 function,另一个请求定义两个参数 function。 However, there would be an enormous amount of code being copy and pasted between the two base class' definition of final_result() .但是,在final_result()的两个基类定义之间会复制和粘贴大量代码。 This is why I'm asking, so I don't write WET code.这就是我问的原因,所以我不写 WET 代码。

Another option would be to have one pure virtual function, but change the signature so that its implementation can do either of these things.另一种选择是拥有一个纯虚拟 function,但更改签名以便其实现可以执行上述任何一项操作。 I want to explore this, but I also don't want to start using fancier techniques so that it puts a barrier to entry on the type of people trying to inherit from these base classes.我想探索这一点,但我也不想开始使用更高级的技术,这样它就会对试图从这些基类继承的人设置障碍。 Ideally, if the writers of the base class could get away with barely knowing any c++, that would be great.理想情况下,如果基础 class 的编写者能够侥幸逃脱几乎不知道任何 c++ 的情况,那就太好了。 Also, it would be ideal if the inheritors didn't even have to know about the existence of related classes they could be writing.此外,如果继承者甚至不必知道他们可能正在编写的相关类的存在,那将是理想的。

#include <iostream>

class base{
public:
    virtual int first(int a) = 0;
    int final_result(int a) {
        return 3*first(a);
    }   
};

class derived : public base {
public:
    int first(int a) {
        return 2*a;
    }
};

class another_derived : public base {
public:
    int first(int a, int b) {
        return a + b;
    }

};

int main() {

    derived d;
    std::cout << d.final_result(1) << "\n";
    //another_derived d2; // doesn't work
    return 0;
}

Not sure it matches exactly what you want, but with CRTP, you might do something like:不确定它是否完全符合您的要求,但使用 CRTP,您可能会执行以下操作:

template <typename Derived>
struct MulBy3
{
    template <typename... Ts>
    int final_result(Ts... args) { return 3 * static_cast<Derived&>(*this).first(args...); }
};

class derived : public MulBy3<derived> {
public:
    int first(int a) { return 2*a; }
};

class another_derived : public MulBy3<another_derived > {
public:
    int first(int a, int b) { return a + b; }
};

With usage similar to用法类似于

int main() {
    derived d;
    std::cout << d.final_result(1) << "\n";
    another_derived d2;
    std::cout << d2.final_result(10, 4) << "\n";
}

Demo演示

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM