c++ - 与 std::list 一起使用的指针上的接口(interface)类型转换的多重继承

标签 c++ class oop casting multiple-inheritance

我有 Java (OOP) 背景。我做了一个简单的类来说明我的问题:

#include <list>
#include <string>
#include <iostream>

// classes
class InterfaceA
{
public:
    virtual std::string functionA();
};

class InterfaceB
{
public:
    virtual std::string functionB();
};

class DerivedAB : public InterfaceA, public InterfaceB
{
public:
    std::string functionA()
    {
        return "I'm a A object";
    }

    std::string functionB()
    {
        return "I'm a B object";
    }
};

// functions
void doStuffOnListOfA(std::list<InterfaceA*> aElements)
{
    std::cout << "Print list of A" << std::endl;
    for (InterfaceA* const& a : aElements)
    {
        std::cout << a->functionA() << std::endl;
    }
};

int main()
{
    std::list<DerivedAB*> derivedABs;   
    doStuffOnListOfA(derivedABs);
    return 0;
}

我有两个简单的虚拟类 InterfaceAInterfaceB和一个类DerivedAB该多重继承了前两个虚拟类。

此外,我还创建了一个 DerivedAB 的指针列表。 ( std::list<DerivedAB *> ) 并希望将此列表与设计用于处理 InterfaceA 列表的函数一起使用。 -派生对象。但我收到一个错误:

(base)  ❮ onyr ★  kenzae❯ ❮ multi_inheritance_type_convertion❯❯ make
g++    -c -o main.o main.cpp
main.cpp: In function ‘int main()’:
main.cpp:54:32: error: could not convert ‘derivedABs’ from ‘std::__cxx11::list<DerivedAB*>’ to ‘std::__cxx11::list<InterfaceA*>’
     doStuffOnListOfA(derivedABs);                               

我显然有一个类型转换错误。我在 Stack Overflow 上读过很多关于 C++ 中的不同类型转换以及多重继承的文章,但我的大脑拒绝给我答案。


编辑:

我说了一个错误的说法:

"However I'm pretty sure such a code would work in Java..."

显然我缺少一个关于类型继承的重要概念......

最佳答案

C++ 与 Java 有很大不同!


I have obviously a type casting error.

你是对的(又名:类型不匹配)! std::list是一个标准模板容器,当您使用模板参数实例化时,它为您提供具体类型。 这意味着 std::list<InterfaceA*>std::list<DerivedAB *> 不同.

这正是编译器告诉您的:

error: could not convert 
from ‘std::__cxx11::list<DerivedAB*>’     ----> i.e. std::list<DerivedAB*>
to    ‘std::__cxx11::list<InterfaceA*>’   ----> i.e  std::list<InterfaceA*>
     doStuffOnListOfA(derivedABs);        ----> at the function call

您不能隐式(即编译器不会)相互转换。

您需要强制转换 derivedABs 的每个元素到基指针或(在你的情况下)使 doStuffOnListOfA作为模板函数:

template<typename T>
void doStuffOnListOfA(std::list<T*> aElements)
{
    std::cout << "Print list of A" << std::endl;
    for (InterfaceA* a : aElements)
    {
        std::cout << a->functionA() << std::endl;
    }
};

为了确保这一点,仅将上述内容用于 std::list<derived from InterfaceA and B> ,您可以(可选)SFINAE模板函数:

#include <type_traits> // std::is_base_of

template<typename T>
constexpr bool isBaseOfInterfaces = std::is_base_of_v<InterfaceA, T> && std::is_base_of_v<InterfaceB, T>;

template<typename T>
auto doStuffOnListOfA(std::list<T*> aElements) 
    -> std::enable_if_t<isBaseOfInterfaces<T>, void>
{
    // ... code
};

话虽如此,

这里是( the complete demo )

关于c++ - 与 std::list 一起使用的指针上的接口(interface)类型转换的多重继承,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68806059/

相关文章:

C++编译失败,错误: no member named 'snprintf' in namespace 'std'

PHP OOP - 如何处理身份验证?

java - 这在 oop java 中如何工作?

c++ - QCheckbox:未发出 stateChanged 信号

c++ - 在哪里保存我的 C++ 库? (Ubuntu)

python - 两个不同的 Python 类与同一底层对象共享属性

swift - 用户希望在文本字段中输入整数

c++ - 定义类 X 的析构函数,它继承自指向对象 Y 的指针 vector 并具有指向 Z 的指针数组

c++ - fatal error : iostream: No such file or directory #include <iostream>

python - Cython 扩展类型是否支持类属性?