指向模板化虚拟基类的指针的问题

Issue with pointers to templated virtual base class

提问人:Nilsie 提问时间:10/31/2023 最后编辑:Jarod42Nilsie 更新时间:10/31/2023 访问量:38

问:

定义接口的常规方法使用虚拟基类,例如:

class BaseClass_B
{
public:
    BaseClass_B() {}
    virtual ~BaseClass_B() {}
    virtual void method(const int &fParam) const = 0;
};

template <class tDerivedClassParam>
class DerivedClass_B : public BaseClass_B
{
    void method(const int &fParam) const override final
    {
        // Do something useful
    }

};

class FinalClass_B
{
public:
    using TypeAlias = int;
};

然后,我可以创建一个派生对象,并将其地址分配给派生对象指针和基指针:

DerivedClass_B<FinalClass_B> object_B;
DerivedClass_B<FinalClass_B> *ptr_B;
BaseClass_B *basePtr_B;

ptr_B = &object_B;
basePtr_B = &object_B;

但是,当我尝试做同样的事情时,有一个模板化的虚拟基类:

template <class tBaseClassParam>
class BaseClass_A
{
public:
    BaseClass_A() {}
    virtual ~BaseClass_A() {}
    virtual void method(const int &fParam) const = 0;
};

//
// Note that BaseClass_A<> is defined using a type alias from FinalClass_A
//
template <class tDerivedClassParam>
class DerivedClass_A : public BaseClass_A<typename tDerivedClassParam::TypeAlias>
{
    void method(const int &fParam) const override final
    {
        // Doe something useful
    }
};

class FinalClass_A
{
public:
    using TypeAlias = int;
};

尝试时,我在最后一行出现错误:

DerivedClass_A<FinalClass_A> object_A;
DerivedClass_A<FinalClass_A> *ptr_A;
BaseClass_A<FinalClass_A> *basePtr_A;

ptr_A = &object_A;
basePtr_A = &object_A;  //<-- Generates error

我得到的编译器错误是:

error: cannot convert ‘DerivedClass_A<FinalClass_A>*’ to ‘BaseClass_A<FinalClass_A>*’ in assignment

我错过了什么???

顺便说一句,我在 C++14 上。

C++ 模板 虚拟

评论

0赞 aschepler 10/31/2023
“虚拟基类”的含义与使用它的方式不同。你可以说这是一个“接口基类”。
1赞 Pepijn Kramer 10/31/2023
一般来说,模板(静态多态性)和虚拟函数不能很好地混合在一起。

答:

3赞 Ted Lyngmo 10/31/2023 #1

我错过了什么???

basePtr_A不是指向 A 或其基类的指针。DerivedClass_A<FinalClass_A>

BaseClass_A<FinalClass_A::TypeAlias>* basePtr_A;将是您可以在赋值中使用的基类指针。basePtr_A = &object_A;


使该赋值起作用的另一种选择是更改以下定义:DerivedClass_A

template <class tDerivedClassParam>
class DerivedClass_A : public BaseClass_A<tDerivedClassParam> {
    void method(const int &fParam) const override final {
    }
};