一.用dynamic_cast的方式返回类的名称
#include <iostream>
#include <string>
#include <vector>
#include <memory>
using namespace std;
class Cat;
class Dog;
class Mouse;
class IVisitor //这里是可以将这个类直接放在Animal类外面的,放在里面主要是让代码更紧凑。
{
public:
virtual ~IVisitor()
{
}
/*这里为什么不直接将函数的全部内容都定义出来呢,还要分成一个父类一个子类,
再在子类中把函数完成?
因为如果整合为一个只放在前面,则animal->introduce()这个函数识别不出来,
因为还没有被定义。
而如果把他们都放在后面,则每个类里的Visitor->visit()函数又识别不了,因为
在代码前面没有定义。
所以把父类放在前面,可以有Visitor->visit()函数的定义,然后在把子类放在
后面这个时候animal->introduce()已经有了,则可以重载虚函数实现*/
virtual void Visit(Cat* animal) = 0;
virtual void Visit(Dog* animal) = 0;
virtual void Visit(Mouse* animal) = 0;
};
class Animal//:public IVisitor
{
public:
// class IVisitor{
// public:
// virtual ~IVisitor()
// {
// }
// virtual void Visit(Cat* animal) = 0;
// virtual void Visit(Dog* animal) = 0;
// virtual void Visit(Mouse* animal) = 0;
// };
// private:
// string name;
// public:
Animal(const string& theName)
:name{theName}
{
}
virtual ~Animal()
{
}
const string& GetName()const
{
return name;
}
virtual string Introduce() const = 0;
virtual void Accept(IVisitor* visitor) = 0;
private:
string name;
};
class Cat : public Animal
{
public:
Cat(const string& theName)
:Animal{theName}
{
}
string Introduce()const override
{
return "我是一只猫,我的名字叫\"" + GetName() + "\"。";
}
void Accept(IVisitor* visitor)override
{
visitor->Visit(this);
}
};
class Dog : public Animal
{
public:
Dog(const string& theName)
:Animal{theName}
{
}
string Introduce()const override
{
return "我是一只狗,我的名字叫\"" + GetName() + "\"。";
}
void Accept(IVisitor* visitor)override
{
visitor->Visit(this);
}
};
class Mouse : public Animal
{
public:
Mouse(const string& theName)
:Animal{theName}
{
}
string Introduce()const override
{
return "我是一只老鼠,我的名字叫\"" + GetName() + "\"。";
}
void Accept(IVisitor* visitor)override
{
visitor->Visit(this);
}
};
class OnlyPrintCatVisitor:public IVisitor
{
public:
void Visit(Cat* animal)override
{
cout<<animal->Introduce()<<endl;
}
void Visit(Dog* animal)override
{
}
void Visit(Mouse* animal)override
{
}
};
class OnlyPrintVisitor
{
public:
void Visit(Cat* animal)
{
cout<<animal->Introduce()<<endl;
}
void Visit(Dog* animal)
{
}
void Visit(Mouse* animal)
{
}
};
int main()
{
Cat *tom =new Cat("Tom");
auto jerry =new Mouse("Jerry");
auto spike =new Dog("Spike");
auto butch =new Cat("Butch");
auto lightning =new Cat("Lightning");
vector<Animal*> friends{ tom, jerry, spike, butch, lightning };
//OnlyPrintCatVisitor visitor;
for (auto animal : friends)
{
Cat *cat =dynamic_cast<Cat *> (animal);
Dog *dog =dynamic_cast<Dog *> (animal);
Mouse *mouse =dynamic_cast<Mouse *> (animal);
if(cat!=nullptr)
{
cout << cat->Introduce() <<endl;
}
// else if(dog!=nullptr)
// {
// cout << dog->Introduce() <<endl;
// }
// else if(mouse!=nullptr)
// {
// cout << mouse->Introduce() <<endl;
// }
}
return 0;
}
二.通过智能指针实现查找。
#include <iostream>
#include <string>
#include <vector>
#include <memory>
using namespace std;
class Cat;
class Dog;
class Mouse;
class IVisitor
{
public:
virtual ~IVisitor()
{
}
virtual void Visit(Cat* animal) = 0;
virtual void Visit(Dog* animal) = 0;
virtual void Visit(Mouse* animal) = 0;
};
class Animal//:public IVisitor
{
public:
// class IVisitor{
// public:
// virtual ~IVisitor()
// {
// }
// virtual void Visit(Cat* animal) = 0;
// virtual void Visit(Dog* animal) = 0;
// virtual void Visit(Mouse* animal) = 0;
// };
// private:
// string name;
// public:
Animal(const string& theName)
:name{theName}
{
}
virtual ~Animal()
{
}
const string& GetName()const
{
return name;
}
virtual string Introduce() const = 0;
virtual void Accept(IVisitor* visitor) = 0;
private:
string name;
};
class Cat : public Animal
{
public:
Cat(const string& theName)
:Animal{theName}
{
}
string Introduce()const override
{
return "我是一只猫,我的名字叫\"" + GetName() + "\"。";
}
void Accept(IVisitor* visitor)override
{
visitor->Visit(this);
}
};
class Dog : public Animal
{
public:
Dog(const string& theName)
:Animal{theName}
{
}
string Introduce()const override
{
return "我是一只狗,我的名字叫\"" + GetName() + "\"。";
}
void Accept(IVisitor* visitor)override
{
visitor->Visit(this);
}
};
class Mouse : public Animal
{
public:
Mouse(const string& theName)
:Animal{theName}
{
}
string Introduce()const override
{
return "我是一只老鼠,我的名字叫\"" + GetName() + "\"。";
}
void Accept(IVisitor* visitor)override
{
visitor->Visit(this);
}
};
class OnlyPrintCatVisitor:public IVisitor
{
public:
void Visit(Cat* animal)override
{
cout<<animal->Introduce()<<endl;
}
void Visit(Dog* animal)override
{
}
void Visit(Mouse* animal)override
{
}
};
class OnlyPrintVisitor
{
public:
void Visit(Cat* animal)
{
cout<<animal->Introduce()<<endl;
}
void Visit(Dog* animal)
{
}
void Visit(Mouse* animal)
{
}
};
int main()
{
auto tom = make_shared<Cat>("Tom");
auto jerry = make_shared<Mouse>("Jerry");
auto spike = make_shared<Dog>("Spike");
auto butch = make_shared<Cat>("Butch");
auto lightning = make_shared<Cat>("Lightning");
vector<shared_ptr<Animal>> friends{ tom, jerry, spike, butch, lightning };
OnlyPrintCatVisitor visitor;
for (auto animal : friends)
{
animal->Accept(&visitor);
}
return 0;
}