C++用dynamic_cast与visitor模式返回类的名称

一.用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;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值