stl :: list中的C ++接口

时间:2009-10-21 15:05:36

标签: c++

LessonInterface

class ILesson
{
    public:
        virtual void PrintLessonName() = 0;
        virtual ~ILesson() {}
};

stl container

typedef list<ILesson> TLessonList;

调用代码

for (TLessonList::const_iterator i = lessons.begin(); i != lessons.end(); i++)
    {
        i->PrintLessonName();
    }

错误:

  

描述资源路径位置类型   将'const ILesson'传递为'this'   “虚拟虚空”的论证   ILesson :: PrintLessonName()'丢弃   限定符

8 个答案:

答案 0 :(得分:10)

PrintLessonName必须声明为const才能在const ILessons上调用。否则,编译器会假定它可能会修改ILesson并阻止调用。

virtual void PrintLessonName() const = 0;

答案 1 :(得分:7)

您不能“放置”具有纯虚函数的类的对象(因为您无法实例化它)。也许你的意思是:

// store a pointer which points to a child actually.
typedef list<ILesson*> TLessonList;

好的,正如其他人指出的那样,你必须让PrintLessonName成为const成员函数。我想补充一点,这里还有另一个小陷阱。 PrintLessonNameconst类中的base必须为derived,否则 的签名不会相同:

class ILesson
{
public:
    virtual void PrintLessonName() const = 0;
    virtual ~ILesson() {}
};


class SomeLesson : public ILesson
{
public:
    // const is mandatory in the child
    virtual void PrintLessonName() const
    {
        //
    }
    virtual ~SomeLesson() {}
};

说实话,我发现Jerry Coffin's回答有助于重新设计打印功能。

答案 2 :(得分:3)

使用iterator代替const_iterator或使PrintLessonName() const函数:

virtual void PrintLessonName() const = 0

答案 3 :(得分:3)

你必须使PrinLessonName const。

virtual void PrintLessonName() const = 0;

当然,或者不使用const_iterator。

答案 4 :(得分:3)

你想要一个指向ILesson的指针列表。

IMO,你在添加类似的东西方面也会好得多:

std::ostream &operator<<(std::ostream &os, ILesson const *il) { 
    il->PrintLessonName(os);
    return os;
}

然后,您可以使用类似:

之类的内容,而不是上面写的循环
std::copy(lessons.begin(), lessons.end(), 
          std::ostream_iterator<ILesson *>(std::cout));

正如您所看到的,我在此过程中添加了另一个小修饰--PrintLessonName将流作为其参数,而不是始终打印到同一位置。当然,如果你不使用流,你可能不希望这样......

编辑:当然你要制作PrintLessonPlan const的其他注释也是正确的......

答案 5 :(得分:1)

通过对const对象的引用,为const对象调用非const方法。

反正:

我100%确定你需要一个指针列表:

typedef list<ILesson*> TLessonList;

为了利用多态性。

有一个ILesson值列表是不可能的,因为ILesson是一个抽象类。

不要忘记删除指针列表中的对象,以避免内存泄漏。

答案 6 :(得分:1)

这样的版本:

for (TLessonList::const_iterator i=lessons.begin(), m=lessons.end();  i!=m;  ++i)
    {
        i->PrintLessonName();
    }
每次调用lesson.end(),并注意++ i而不是i ++,这更快(后增量运算符涉及创建临时对象,而预增量不会)。

答案 7 :(得分:0)

人们对缺乏常识是正确的。 我赞成使用for_each算法,这会阻止为每个条目调用lessons.end()。

#include <algorithm> //for for_each()

然后使用:

std::for_each(  lessons.begin(), lessons.end(), std::mem_fun(&ILesson::PrintLessonName) )