简体   繁体   English

stl :: list中的C ++接口

[英]C++ Interfaces in stl::list

LessonInterface LessonInterface

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

stl container stl容器

typedef list<ILesson> TLessonList;

calling code 调用代码

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

The error: 错误:

Description Resource Path Location Type passing 'const ILesson' as 'this' argument of 'virtual void ILesson::PrintLessonName()' discards qualifiers 描述资源路径位置类型将'const ILesson'作为'this'参数传递给'virtual void ILesson :: PrintLessonName()',丢弃限定符

PrintLessonName must be declared as const to be able to be called on const ILessons. 必须将PrintLessonName声明为const才能在const ILessons上调用。 Otherwise the compiler assumes it may modify the ILesson and prevents the call. 否则,编译器会假定它可能会修改ILesson并阻止调用。

virtual void PrintLessonName() const = 0;

You can't "put" objects of a class that has pure virtual functions(because you can't instantiate it). 您不能“放置”具有纯虚函数的类的对象(因为您无法实例化它)。 Maybe you mean: 也许你的意思是:

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

OK, as others pointed out, you have to make PrintLessonName a const member function. 好的,正如其他人指出的那样,你必须使PrintLessonName成为一个const成员函数。 I would add that there is another small pitfall here. 我想补充一点,这里还有另一个小陷阱。 PrintLessonName must be const in both the base and the derived classes, otherwise they will not have the same signature: PrintLessonNamebase类和derived类中必须是const ,否则它们将具有相同的签名:

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() {}
};

To be honest, I find Jerry Coffin's answer helpful for redesigning the printing functionality. 说实话,我发现Jerry Coffin的回答有助于重新设计打印功能。

使用iterator而不是const_iterator或make PrintLessonName() const函数:

virtual void PrintLessonName() const = 0

You have to make PrinLessonName const. 你必须使PrinLessonName const。

virtual void PrintLessonName() const = 0;

Or not use a const_iterator, of course. 当然,或者不使用const_iterator。

You want a list of pointers to ILesson's. 你想要一个指向ILesson的指针列表。

IMO, you'd also be considerably better off adding something like: IMO,你也可以更好地添加以下内容:

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

Then, instead of the loop you've written above, you can use something like: 然后,您可以使用以下内容代替上面所写的循环:

std::copy(lessons.begin(), lessons.end(), 
          std::ostream_iterator<ILesson *>(std::cout));

As you can see, I've added one other minor embellishment in the process -- PrintLessonName takes a stream as its argument, instead of always printing to the same place. 正如您所看到的,我在此过程中添加了另一个小修饰--PrintLessonName将流作为其参数,而不是始终打印到同一位置。 Of course, if you're not using streams, you may not want that... 当然,如果你不使用溪流,你可能不希望......

Edit: Of course the other comments that you want to make PrintLessonPlan const are also correct... 编辑:当然你要使PrintLessonPlan const的其他注释也正确...

You call a non-const method for a const object refered through a reference to const object. 通过对const对象的引用,为const对象调用非const方法。

Anyways: 无论如何:

I'm 100% sure you need to have a list of pointers: 我100%确定你需要一个指针列表:

typedef list<ILesson*> TLessonList;

in order to take advantage of polymorphism. 为了利用多态性。

Having a list of values of ILesson is not possible, since ILesson is an abstract class. 由于ILesson是一个抽象类,因此无法获得ILesson的值列表。

Don't forget to delete the objects in the list of pointers, to avoid memory leaks. 不要忘记删除指针列表中的对象,以避免内存泄漏。

A version like this: 像这样的版本:

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

lessons.end() gets called once, and also note ++i instead of i++, which is faster (the post-increment operator involves creation of a temporary object, while the pre-increment doesn't). lessons.end()被调用一次,并且还注意++ i而不是i ++,这更快(后增量运算符涉及创建临时对象,而预增量不会)。

People are correct about the lack of const. 人们对缺乏常识是正确的。 I'd favour using the for_each algorithm this will prevent calling lessons.end() for every entry. 我赞成使用for_each算法,这将阻止为每个条目调用lessons.end()。

#include <algorithm> //for for_each()

Then use this: 然后用这个:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM