11.测试智能指针
//TestMySmartPointer.h #pragma once #if defined(_MSC_VER) #pragma warning ( disable : 4786 ) #endif #include "MySmartPointer.h" #include <iostream> #include <cstdlib> //测试类基类,测试智能指针:MySmartPointer class MyTestObject { public: typedef MyTestObject Self; typedef MySmartPointer<MyTestObject> Pointer; typedef MySmartPointer<const MyTestObject> ConstPointer; //创建对象 static MyTestObject::Pointer New(); //增加/减少 引用计数 virtual void Register() { std::cout << "Register " << *this << " count:" << (m_ReferenceCount+1) << " " << std::endl; m_ReferenceCount++; } virtual void UnRegister() { std::cout << "UnRegister " << this << " count:" << (m_ReferenceCount-1) << " " << std::endl; m_ReferenceCount--; if ( m_ReferenceCount == 0 ) { delete this; } } //operator << inline friend std::ostream &operator << ( std::ostream &os, MyTestObject const& o) { os << "MyTestObject " << (void const * )&o << " " << o.m_ReferenceCount; return os; } protected: MyTestObject() { m_ReferenceCount = 0; // cout << *this 会调用上面重载的友员函数 std::cout << "MyTestObject(): " << *this << std::endl; } virtual ~MyTestObject() { std::cout << "~MyTestObject(): " << *this << std::endl; } private: unsigned int m_ReferenceCount; }; // MyTestObject::Pointer MyTestObject::New() { return MyTestObject::Pointer(new MyTestObject); } //测试子类, 继承自 MyTestObject class MyTestObjectSubClass : public MyTestObject { public: typedef MyTestObjectSubClass Self; typedef MyTestObject Superclass; typedef MySmartPointer<MyTestObjectSubClass> Pointer; typedef MySmartPointer<const MyTestObjectSubClass> ConstPointer; // static Pointer New(); }; // MyTestObjectSubClass::Pointer MyTestObjectSubClass::New() { return MyTestObjectSubClass::Pointer(new MyTestObjectSubClass); } //测试向上类型转换,其参数为基类智能指针 void TestUpCastPointer(MyTestObject::Pointer) { std::cout << "TestUpCastPointer()... " << std::endl; } //测试向上类型转换,其参数为基类原始指针 void TestUpCast(MyTestObject*) { std::cout << "TestUpCast()... " << std::endl; } //测试向上类型转换,其参数为基类原始指针 void TestCopyConstruct(MySmartPointer<MyTestObject> s) { std::cout << "TestCopyConstruct()... " << std::endl; } //用于测试的函数 int MySmartPointerTest(int argc, char* argv[] ) { std::cout << "Test MySmartPointer start:/n" << std::endl; //新建一个基类指针,指向一个具体的子类对象 MyTestObject::Pointer to(MyTestObjectSubClass::New()); //1.创建子类指针,构造,+1; 2.有参构造 to, +1; 3.离开作用范围,析构, -1; count=1; std::cout << "-------------------------------------------1" << std::endl; //测试安全向下类型转换 //使用 dynamic_cast 将上面的指向子类对象的基类指针转换为子类指针 MyTestObjectSubClass::Pointer sc = dynamic_cast<MyTestObjectSubClass*>(to.GetPointer()); //1.构造 sc, count=2; std::cout << "-------------------------------------------2" << std::endl; //测试向上转换类型,该函数接收一个基类原始指针 TestUpCast(sc); //1.向上类型转换,什么都没做. std::cout << "-------------------------------------------3" << std::endl; //测试向上转换类型,该函数接收一个基类智能指针 TestUpCastPointer(sc.GetPointer()); //1.该函数参数为 MyTestObject::Pointer,先调用构造一个指向基类的指针, count=3; //2.离开该函数作用域后, 析构, count=2; std::cout << "-------------------------------------------4" << std::endl; //This will not work, but only in construction //itkTestObject::Pointer p = sc; // For construction use the constructor call: // Test casting up the tree, note no explict cast is required MyTestObject::Pointer p(sc); //1.有参构造, +1, to=3; std::cout << "-------------------------------------------5" << std::endl; // No cast is required for assignment p = sc; //1.调用 operator=,先减少左边引用计数,再增加右边引用计数,持平. count=3; std::cout << "-------------------------------------------6" << std::endl; std::cout <<"second test" << std::endl; { MyTestObject::Pointer o1 = MyTestObject::New(); std::cout << "o1 " << &o1 << std::endl; MyTestObject::Pointer o2 = MyTestObject::New(); std::cout << "o2 " << &o2 << std::endl; MyTestObject::Pointer o3 = MyTestObject::New(); std::cout << "o3 " << &o3 << std::endl; MyTestObject::Pointer o4 = MyTestObject::New(); std::cout << "o4 " << &o4 << std::endl; std::cout << "-------------------------------------------7" << std::endl; o1 = o2; //1.o1 引用计数减 1, 析构. 2. o2 引用计数加 1, = 2; std::cout << "---------------8" << std::endl; o2 = o3; //1.o2 引用计数减 1, =1; 2. o3 引用计数加 1, = 2; std::cout << "---------------9" << std::endl; o4 = o1; //1.o4 引用计数减 1, 析构. 2. o1, 即 o2 引用计数加 1, = 2; std::cout << "---------------10" << std::endl; //至此,o1=0, o2=2, o3=2; o4=0; //1. o4 析构, 即 o2 减 1; 2. o3 析构, 即 o3 减 1; //3. o2 析构, 即 o3 减 1; o3 指向的对象最终析构. //4. o1 析构, 即 o3 析构; o2 指向的对象最终析构. } std::cout <<"end second test" << std::endl << std::endl; std::cout <<"first test" << std::endl; { MyTestObject::Pointer o1 = MyTestObject::New(); //1. 构造 MyTestObject; 2. 构造其智能指针; //3. 智能指针离开作用域,析构,引用计数减 1, 为 0; //4. 其指向的对象析构. } std::cout <<"end first test" << std::endl << std::endl; //看拷贝构造函数 { MyTestObject::Pointer o1 = MyTestObject::New(); std::cout << "------------------------11" << std::endl; MyTestObject::Pointer o2; //默认构造函数 std::cout << "------------------------12" << std::endl; TestCopyConstruct(o1); //该函数的参数为一个对象, 向函数按值传递参数, 会调用拷贝构造函数 std::cout << "------------------------13" << std::endl; } std::cout << std::endl; //1.最后,刚开始创建的对象引用计数 从 3 减少至 0, 然后析构. return EXIT_SUCCESS; }
12.测试对象工厂
//TestMyObjectFactory.h #pragma once #if defined(_MSC_VER) #pragma warning ( disable : 4786 ) #endif #include "MyObjectFactory.h" #include <string> #include <list> //测试对象工厂: //1.对象工厂可以在运行时进行动态替换 //2.我们从 MyObject 继承得到两个版本的类: TestObject1, TestObject2 //然后创建一个创建该类对象的对象工厂, 并在开始时设置创建版本 TestObject1 //运行时, 通过设置 m_EnabledFlag变量, 可以将其动态替换为版本 TestObject2 // //版本1 class TestObject1 : public MyObject { public: typedef TestObject1 Self; typedef MyObject Superclass; typedef MySmartPointer<Self> Pointer; typedef MySmartPointer<const Self> ConstPointer; //通过对象工厂创建对象实例,返回指向对象实例的智能指针 MyNewMacro(Self); //virtual const char *GetNameOfClass() const; MyTypeMacro(TestObject1, MyObject); // virtual ~TestObject1() { } TestObject1(){ } private: TestObject1(const Self&); void operator=(const Self&); }; //版本2 class TestObject2 : public MyObject { public: typedef TestObject2 Self; typedef MyObject Superclass; typedef MySmartPointer<Self> Pointer; typedef MySmartPointer<const Self> ConstPointer; //通过对象工厂创建对象实例,返回指向对象实例的智能指针 MyNewMacro(Self); //virtual const char *GetNameOfClass() const; MyTypeMacro(TestObject2, MyObject); // virtual ~TestObject2() { } TestObject2(){ } private: TestObject2(const Self&); void operator=(const Self&); }; //用于创建 TestObject1, TestObject2 的对象工厂. class TestFactory : public MyObjectFactoryBase { public: typedef TestFactory Self; typedef MyObjectFactoryBase Superclass; typedef MySmartPointer<Self> Pointer; typedef MySmartPointer<const Self> ConstPointer; //描述该对象工厂... const char* GetDescription() const { return "A Test Factory"; } //使用 new 操作符实例化对象工厂 MyFactorylessNewMacro(Self); MyTypeMacro(TestFactory, MyObjectFactoryBase); //注册该对象工厂. static void RegisterOneFactory(void) { TestFactory::Pointer factory = TestFactory::New(); //调用对象工厂基类的静态方法 MyObjectFactoryBase::RegisterFactory(factory); } private: TestFactory(const Self&); void operator=(const Self&); //构造函数 //注册其能创建的对象,及其版本信息与描述 TestFactory() { //TestFactory 可以创建两种对象: TestObject1, TestObject2; this->RegisterOverride( typeid(MyObject).name(), //父类 typeid(TestObject1).name(), //自己 "Test Object factory override 1", //对工厂的描述 true, //true, 默认创建该版本 MyCreateObjectFunction< TestObject1 >::New() ); //用于创建该对象的回调函数 this->RegisterOverride( typeid(MyObject).name(), typeid(TestObject2).name(), "Test Object factory override 2", false, //false, 不创建该版本 MyCreateObjectFunction< TestObject2 >::New()); } }; //测试指针 v 所指的对象是否是 expectedClassName 类的对象实例. typedef MyObject::Pointer myPointer; bool TestNewObject(myPointer v, const char* expectedClassName) { std::cout << "v->GetNameOfClass(): " << v->GetNameOfClass(); std::cout << ", expectedClassName: " << expectedClassName << std::endl; if(strcmp(v->GetNameOfClass(), expectedClassName) != 0) { std::cout << "Test Failed" << std::endl; return false; } return true; } //测试对象工厂 int MyObjectFactoryTest(int argc, char* argv[]) { TestFactory::Pointer factory = TestFactory::New(); MyObjectFactoryBase::RegisterFactory(factory); //列出所有已经注册的对象工厂 std::list<MyObjectFactoryBase *> factories = MyObjectFactoryBase::GetRegisteredFactories(); //打印已经注册的对象工厂的信息 //依次打印对象工厂链表上的各个对象工厂的信息, 当然这里只注册了一个对象工厂 std::cout << "-------- Registered factories --------" << std::endl; for ( std::list<MyObjectFactoryBase*>::iterator f = factories.begin(); f != factories.end(); ++f ) { std::cout << " Factory description: " << (*f)->GetDescription() << std::endl; std::list<std::string> overrides = (*f)->GetClassOverrideNames(); std::list<std::string> names = (*f)->GetClassOverrideWithNames(); std::list<bool> enableflags = (*f)->GetEnableFlags(); std::list<std::string> descriptions = (*f)->GetClassOverrideDescriptions(); std::list<std::string>::const_iterator n = names.begin(); std::list<std::string>::const_iterator d = descriptions.begin(); std::list<bool>::const_iterator e = enableflags.begin(); //每个对象工厂可能能够创建同一对象的多种不同版本, 分别打印 for ( std::list<std::string>::const_iterator o = overrides.begin(); o != overrides.end(); ++o, ++n, ++d, ++e) { std::cout << " Override " << *o << " with " << *n << std::endl << " described as /"" << *d << "/"" << std::endl << " enabled " << *e << std::endl; } } std::cout << "----------- -----------" << std::endl; //*/ //Tets1: 测试是否能够创建版本 TestObject1 的实例 MyObject::Pointer v = MyObject::New(); int status = EXIT_SUCCESS; if (!TestNewObject(v, "TestObject1")) //Success { status = EXIT_FAILURE; }//*/ std::cout << "-------------------------------------------------------1" << std::endl; //Test2: 关闭 ID 为 MyObject 的对象工厂, 这时无法创建 TestObject1 与 TestObject2 factory->Disable(typeid(MyObject).name()); v = MyObject::New(); //所以该语句得到的就是 MyObject if (!TestNewObject(v, "MyObject")) { status = EXIT_FAILURE; } std::cout << "-------------------------------------------------------2" << std::endl; //Test3: 打开 ID 为 MyObject 的对象工厂, 并输出其相关信息进行验证 factory->SetEnableFlag(true, typeid(MyObject).name(), typeid(TestObject2).name()); //使其能够创建版本 TestObject2 std::cout << typeid(MyObject).name() << " overridden by " << typeid(TestObject2).name() << std::endl << " EnableFlag is " << factory->GetEnableFlag(typeid(MyObject).name(), typeid(TestObject2).name()) << std::endl; v = MyObject::New(); if (!TestNewObject(v, "TestObject2")) { status = EXIT_FAILURE; } std::cout << "-------------------------------------------------------3" << std::endl; //Test4: 设置工厂可以创建版本 TestObject1, 不能创建版本 TestObject2 factory->SetEnableFlag(false, typeid(MyObject).name(), typeid(TestObject2).name()); factory->SetEnableFlag(true, typeid(MyObject).name(), typeid(TestObject1).name()); v = MyObject::New(); if (!TestNewObject(v, "TestObject1")) { status = EXIT_FAILURE; } std::cout << "-------------------------------------------------------4" << std::endl; //Test5: 将所有的对象工厂注销 MyObjectFactoryBase::UnRegisterFactory(factory); v = MyObject::New(); //所以该语句得到的就是 MyObject if (!TestNewObject(v, "MyObject")) { status = EXIT_FAILURE; } std::cout << "-------------------------------------------------------5" << std::endl; //Test6: 注销对象工厂后, 无法创建版本 TestObject1, TestObject2 v = MyObject::New(); if (!TestNewObject(v, "TestObject1")) //注销对象工厂后 Test Failed! { status = EXIT_FAILURE; } std::cout << "-------------------------------------------------------6" << std::endl; //Test7: 注册对象工厂, 恢复到 Test1 的状态. TestFactory::RegisterOneFactory(); //再次注册对象工厂 v = MyObject::New(); if (!TestNewObject(v, "TestObject1")) { status = EXIT_FAILURE; } std::cout << "/nTest MyObjectFactory End...." << std::endl; return status; }
13.主驱动
//Test.cpp //分别测试 MySmartPointer 与 MyObjectFactory #include "TestMySmartPointer.h" #include "TestMyObjectFactory.h" int main(int argc, char* argv[]) { //Test MySmartPointer std::cout << "-----------------------Test MySmartPointer-----------------------/n"; MySmartPointerTest(argc, argv); //Test MyObjectFactory std::cout << "/n-----------------------Test MyObjectFactory----------------------/n"; MyObjectFactoryTest(argc, argv); return EXIT_SUCCESS; }