今天整理了下cppcheck的源码结构,为什么通过写一个个子文件就能够扩展cppcheck的功能呢?
?
看了下代码,并通过简化代码,略懂一二了。
?
? ? 首先我们定义一个基类test.h,只定义一个头文件足够:
?
?
#ifndef TESTH #define TESTH #include<iostream> #include<list> class Test { public: Test(const std::string name); ~Test(){ std::cout << "Test End" << std::endl; } static std::list<Test *> &instances() { static std::list<Test *> _instances; return _instances; } virtual void print() { } }; inline Test::Test(const std::string name) { instances().push_back(this); instances().sort(std::less<Test *>()); } #endif
?
? ? ? 这个基类非常简洁,注意它定义了一个static的Test类指针list,然后初始化的时候直接调用instance函数,相当于生成了预定义了一个list,而print函数是virtual的。
? ? ? 然后我们写一个继承类,先写一个头文件testF.h
?
#ifndef TESTFH #define TESTFH #include"test.h" class TestF : public Test { public: TestF() : Test(myname()) { } std::string myname() const { return "TestF"; } void print(); }; #endif
?
?再写testF.cpp文件:
?
#include"testF.h" namespace{ TestF instance; } void TestF::print() { std::cout << myname() << std::endl; }
? ? ?这个cpp文件直接在namespace初始化了一个TestF实例。这样由于TestF类是继承自Test类,而Test类会生成一个static 的list,而把这个例加入到这个list中,这样子,这个TestF类的实例就加入到了static的list中去了。
? ? ?那我们的main函数就可以这样写了。main.cpp
#include"test.h" #include"testF.h" int main(void) { Test test("Test1"); for(std::list<Test *>::iterator it=test.instances().begin();it != test.instances().end();it++) { (*it)->print(); } }
? ? ? 定义这样一个Test实例只是为了取出本来已经存在的static list中的数据,呵呵。
使用命令:
g++ -o main main.cpp testF.cpp testF.h test.h
然后调用:./main
得到结果:
TestF
Test End
Test End
?
如果我们用TestF test 取代 Test test("test1")呢?
结果是:
TestF
TestF
Test End
Test End
?
你猜猜是为什么?
?
?
?
?
?