【问题标题】:How to instantiate an abstract class with one of the concrete classes?如何用其中一个具体类实例化一个抽象类?
【发布时间】:2018-08-20 15:14:05
【问题描述】:

我想知道以下段落的含义以及如何实现它。我昨天问了一个与同一问题有关的问题here。在昨天的问题中,有人告诉我这是不可能的,但我认为以下段落表明它是不可能的?

您的方法使用特定的求幂方法。然而,幂类是一般类的子类 抽象幂类。您可以实现这些以使用此抽象类,并使用其中一个具体类对其进行实例化。这将使您能够灵活地试验和/或准确更改所使用的取幂算法,例如,如果有人在未来识别出更好的东西......

基本上,我有一堆按以下方式组织的求幂技术-

template <class T>
class Exponentiation
{
    public:
    Exponentiation() {};
    virtual ~Exponentiation() {};

    // computes C = A^n
    virtual void power(T& C, const T& A, const int n) = 0;
}

template <class T>
class ExpA : public Exponentiation<T>
{
    public:
    ExpA() {};
    ~ExpA() {};

    void power (T& C, const T& A, const int n);
}

template <class T>
class ExpB : public Exponentiation<T>
{
    protected:
    var1;
    var2;

    public:
    ExpB() {};
    ~ExpB() {};

    func1();
    func2();
    void power (T& C, const T& A, const int n);
}

现在,最初我有一个 performExp(),它正在调用特定的求幂方法,例如 -

performExp()
{
    ExpA<long> objA;
    objA.power();

    // or

    ExpB<long> objB;
    objB.func1();
    objB.func2();
    obj.power ()
}

但据我所知,更好的选择是使用performExp() 中的基类,然后使用具体类ExpAExpB 之一实例化main() 中的基类。

如何做到这一点?阅读昨天的答案后,我的一个想法是使用某种包装器,但我很难想象它。

【问题讨论】:

  • 您只需将指向基类的指针或引用(取决于情况)传递给您的函数。
  • 查找“多态性”。
  • 您引用的段落有点含糊,但我认为使用Dependency Injection Pattern 可能会满足您的需求。
  • @Slava 我试过你的建议,但它不允许我打电话给 func1func2 。我收到的错误是no member named 'func1' in Exponentiation
  • @Mojo-Jojo 您将调用的所有方法都必须在基类中定义,可能是虚拟的,也可能是纯虚拟的。另一种方法是使用dynamic_cast&lt;&gt;,但这通常是设计不佳的标志。

标签: c++ templates inheritance polymorphism wrapper


【解决方案1】:

我看不到您想要达到的目标。但第一个问题是您是否需要运行时或编译时多态性。看你的代码,我猜是后者。

因此,对于这个答案,我假设您有模板化的幂类,并且您最后编写的 compelx 计算程序将确切知道它们是否适用于 ExpAExpB

然后我建议将performExp() 实现为模板函数,以通用方式指示如何执行操作:

template <class T, template <class U> class Exp>
void performExp(Exp<T>& obj)
{
     obj.power();
}

然后可以为此模板提供特化或部分特化:

template <class T>
void performExp(ExpB<T>& obj)
{
     obj.func1();
     obj.func2(); 
     obj.power();
}

当您在代码中使用这些模板时,编译器将推断参数并使用可能存在的任何特化:

int main() {
    ExpA<long> a;
    performExp(a);

    ExpB<long> b; 
    performExp(b);       //specialized form will be used
}

你可以在这个online demo测试结果

【讨论】:

    猜你喜欢
    • 2019-08-26
    • 2011-03-20
    • 2018-12-15
    • 1970-01-01
    • 1970-01-01
    • 2014-09-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多