繁体   English   中英

默认构造有效的输入迭代器

[英]Default Construction of valid Input Iterators

我正在设计一个输入迭代器类型,它枚举系统中所有正在运行的进程。

这类似于我设计用于枚举进程中的模块的迭代器。 模块迭代器在构造函数中采用“进程”对象,默认构造的迭代器被认为是非现实的迭代器。

例:

hadesmem::ModuleIterator beg(process);
hadesmem::ModuleIterator end;
assert(beg != end);

我不知道如何处理进程枚举,因为没有“状态”或信息需要提供给迭代器(所有内容都由迭代器使用Windows API在内部处理)。

例:

// This is obviously a broken design, what is the best way to distinguish between the two?
hadesmem::ProcessIterator beg;
hadesmem::ProcessIterator end;

处理这种情况的惯用方法是什么? 即,当需要向迭代器构造函数提供任何内容时,您需要区分“新”迭代器和异端迭代器的创建。

如果它是相关的,我可以在这个库中使用C ++ 11,只要它得到VC11,GCC 4.7和ICC 12.1的支持。

谢谢。

编辑:

为了澄清,我知道我不可能在上面发布的形式中区分这两者,所以我要问的是更多的“设计”问题而不是其他任何东西......也许我只是忽略了一些东西虽然很明显(不是第一次)。

你真正想要做的是创建一种ProcessList对象,并在其上建立迭代器。 每次我增加迭代器时,我都不想枚举所有进程或其他东西。

如果您创建一个类,该类包含进入CreateToolhelp32Snapshot()的参数,表示您正在迭代的快照,那么您将拥有一个用于迭代器的自然工厂。 这样的东西应该工作(我不在Windows上,所以没有测试):

class Process;
class Processes {
    DWORD what, who;
public:
    Processes(DWORD what, DWORD who) : what(what), who(who) {}

    class const_iterator {
        HANDLE snapshot;
        LPPROCESSENTRY32 it;
        explicit const_iterator(HANDLE snapshot, LPPROCESSENTRY32 it)
            : snapshot(snapshot), it(it) {}
    public:
        const_iterator() : snapshot(0), it(0) {}

        // the two basic functions, implement iterator requirements with these:
        const_iterator &advance() {
            assert(snapshot);
            if ( it && !Process32Next(snapshot, &it))
                it = 0;
            return *this;
        }
        const Process dereference() const {
            assert(snapshot); assert(it);
            return Process(it);
        }
        bool equals(const const_iterator & other) const {
            return handle == other.handle && it == other.it;
        }
    };

    const_iterator begin() const {
        const HANDLE snapshot = CreateToolhelp32Snapshot(what, who);
        if (snapshot) {
            LPPROCESSENTRY32 it;
            if (Process32First(snapshot, &it))
                return const_iterator(snapshot, it);
        }
        return end();
    }
    const_iterator end() const {
        return const_iterator(snapshot, 0);
    }
};

inline bool operator==(Processes::const_iterator lhs, Processes::const_iterator rhs) {
    return lhs.equals(rhs);
}
inline bool operator!=(Processes::const_iterator lhs, Processes::const_iterator rhs) {
    return !operator==(lhs, rhs);
}

用法:

int main() {
    const Processes processes( TH32CS_SNAPALL, 0 );
    for ( const Process & p : processes )
        // ...
    return 0;
}

您可以使用命名的构造函数idiom

class ProcessIterator
private:
    ProcessIterator(int) //begin iterator
    ProcessIterator(char) //end iterator
    //no default constructor, to prevent mistakes
public:
    friend ProcessIterator begin() {return ProcessIterator(0);}
    friend ProcessIterator end() {return ProcessIterator('\0');}
}

int main() {
    for(auto it=ProcessIterator::begin(); it!=ProcessIterator::end(); ++it)
        //stuff
}

暂无
暂无

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

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