在C+中使用抽象类型时出错+;模板 在C++中实现一个入侵容器时,我遇到了一些奇怪的问题。 给出以下简化代码: struct IFace { virtual int foo() const = 0; }; struct Impl : public IFace { int foo() const { return 111; } }; template <typename T> struct IntrusiveHook { T item; IntrusiveHook<T>* next; }; template <typename T> struct IntrusiveList { IntrusiveList() : head(0), tail(0) {} template <typename U> void add(IntrusiveHook<U>& addItem) { if (0 == head) { head = reinterpret_cast<IntrusiveHook<T>*>(&addItem); tail = head; } else { tail->next = reinterpret_cast<IntrusiveHook<T>*>(&addItem); tail = tail->next; } } IntrusiveHook<T>* head; IntrusiveHook<T>* tail; }; void testList() { IntrusiveHook<Impl> impl; IntrusiveList<IFace> list; list.add(impl); // list.head->item.foo(); }

在C+中使用抽象类型时出错+;模板 在C++中实现一个入侵容器时,我遇到了一些奇怪的问题。 给出以下简化代码: struct IFace { virtual int foo() const = 0; }; struct Impl : public IFace { int foo() const { return 111; } }; template <typename T> struct IntrusiveHook { T item; IntrusiveHook<T>* next; }; template <typename T> struct IntrusiveList { IntrusiveList() : head(0), tail(0) {} template <typename U> void add(IntrusiveHook<U>& addItem) { if (0 == head) { head = reinterpret_cast<IntrusiveHook<T>*>(&addItem); tail = head; } else { tail->next = reinterpret_cast<IntrusiveHook<T>*>(&addItem); tail = tail->next; } } IntrusiveHook<T>* head; IntrusiveHook<T>* tail; }; void testList() { IntrusiveHook<Impl> impl; IntrusiveList<IFace> list; list.add(impl); // list.head->item.foo(); },c++,templates,C++,Templates,当在list.head->item.foo()行中进行注释时,我得到一个不同的编译错误,前一个错误被忽略了(这是一种奇怪的行为,在VC++和gcc编译器上都会发生) 有问题的调用似乎是tail->next=…,尤其是这里使用的抽象类型上的操作符-> 因此: 如何解决这个问题 在IFace中添加foo的默认实现-这不是我想要的,但它解决了问题 一种骇人的解决方案:将代码重写为tail->nextas reinterpret\u cast(tail)->next=&addItem tail=rei

当在
list.head->item.foo()行中进行注释时,我得到一个不同的编译错误,前一个错误被忽略了(这是一种奇怪的行为,在VC++和gcc编译器上都会发生)

有问题的调用似乎是
tail->next=…
,尤其是这里使用的抽象类型上的操作符
->

因此: 如何解决这个问题

  • IFace
    中添加
    foo
    的默认实现-这不是我想要的,但它解决了问题
  • 一种骇人的解决方案:将代码重写为
    tail->next
    as

    reinterpret\u cast(tail)->next=&addItem

    tail=reinterpret\u cast(reinterpret\u cast(tail)->next)-但它似乎不适用于VC++(2010),而是适用于gcc

  • 。。。或者表演一些其他丑陋的演员

但为什么这首先是一个问题?通常,使用运算符“->”访问指针类型应该不会有问题

任何帮助都将不胜感激。谢谢


编辑:

为了方便起见,我希望IntrusiveHook已经包含该项作为实例。这也是入侵的窍门——当我做对的时候——只向项添加指针功能而不更改项本身。“新建”不是选项,因为代码应该在没有
new
的嵌入式环境中运行


当然,我也希望使用带有抽象项的列表,因为使用类不知道实现类。

据我所见,问题是在
IntrusiveList::add
中转换到
IntrusiveHook*
。您正在将
addItem
转换为
IntrusiveHook
<代码>入侵钩子
具有类型为
IFace
的成员
。但是
IFace
是抽象的,因此不能用该类型声明变量——必须使用指针或引用

所以你必须

  • IntrusiveHook::item
    从类型
    T
    更改为
    T*
  • 添加一个构造函数
    IntrusiveHook(T*item):item(item){}
  • testList()
    中的
    impl
    声明更改为
    IntrusiveHook impl(新impl)
  • 最后将
    list.head->item.foo()
    更改为
    list.head->item->foo()
(见附件。)


如果您不想更改
IntrusiveList
列表,也可以使用
IntrusiveList
IntrusiveList
而不是
IntrusiveList
;列表。添加(impl);或
侵入列表;添加(新Impl())正如错误所说:您不能实例化抽象类的对象。您的IntrusiveList不能与
IFace
一起使用,因为这不是一个完整的类型,但它可以与
IFace*
一起使用(因为要声明指针,您不需要知道完整的类型)。对不起,我不能使用“new”-这样会容易得多。使用动态内存时也不需要创建侵入式类型。@michael_s我不熟悉侵入式类型的概念。然而,在C++中,用抽象类型声明变量是不可能的。您必须使用指针、引用或非抽象类。
error C2259: 'IFace' : cannot instantiate abstract class
due to following members:
'int IFace::foo(void) const' : is abstract
testwas.cpp(7) : see declaration of 'IFace::foo'
testwas.cpp(25) : see reference to class template instantiation 'IntrusiveHook<T>' being compiled
with
[
  T=IFace
]
testwas.cpp(41) : see reference to function template instantiation 'void IntrusiveList<T>::add<Impl>(IntrusiveHook<Impl> &)' being compiled
with
[
  T=IFace
]