在另一个类中使用成员方法"generically"

Use member methods in another class "generically"

本文关键字:成员方法 generically 另一个      更新时间:2023-10-16

我想做以下事情:我有一个Person类,我希望能够在其中使用抽象Animal类的任何类型的实现,所以我希望能够在主方法中创建多个人,其中每个人都能够使用狗或猫等,并且这些人应该使用特定的doSomething()方法实现来自特定的狗,猫等。现在的实现不工作,我知道,编译器当然说,动物不能使用doSomething()方法(因为它是虚拟的)。我怎样才能实现我在这里想要做的?

person.h

#include <animal.h>
class Person
{
public:
    Person();
    ~Person();
    Animal *ani;
};
Person::Person (Animal *pointer) 
{
  ani = new Animal ();
}
Person::SomeMethod ()
{
  ani->doSomething ();
}
Person::~Person ()
{
  delete ani;
}

animal.h

class Animal
{
public:
    Animal();
    ~Animal();
    virtual void doSomething () = 0; 
};
class Dog : public Animal
{
public:
    Dog();
    ~Dog();
    void doSomething ();
};
Dog::Dog ()
{
  std::cout << "I've been created!" << std::endl;
}
Dog::doSomething ()
{
  std::cout << "Hello" << std::endl;
}

main.h

#include <animal.h>
#include <person.h>
int main()
{
    Dog *bowser;
    Person *will = new Person (bowser);
    return 0;
}

以下是Person接受任何Animal的示例:

#include <iostream>
class Animal
{
public:
    Animal() = default;
    virtual ~Animal() {};
    virtual void doSomething() = 0;
};
class Person
{
public:
    Person(Animal* pointer); 
    ~Person();
    void SomeMethod();
    Animal *ani;
};
Person::Person(Animal *pointer)
    : ani{pointer} // initialize from passed pointer
{
    //ani = new Animal(); //Person doesn't create/own an animal
}
void Person::SomeMethod()
{
    ani->doSomething();
}
Person::~Person()
{
    //delete ani; // Person doesn't own animal
}
class Dog : public Animal
{
public:
    Dog();
    ~Dog() = default;
    void doSomething();
};
Dog::Dog()
{
    std::cout << "I've been created!" << std::endl;
}
void Dog::doSomething()
{
    std::cout << "Hello" << std::endl;
}
int main()
{
    Dog bowser; // no new here, RAII will take care of killing the Dog
    Dog* bowser_ptr = &bowser;
    Person will(bowser_ptr);
    will.SomeMethod();
    return 0;
}

下面是Person拥有随机Animal的例子:

#include <vector>
#include <iostream>
#include <random>
#include <exception>
class Animal
{
public:
    Animal() = default;
    virtual ~Animal() {}; // must be virtual!
    virtual void doSomething() = 0;
};
class Dog : public Animal
{
public:
    Dog();
    ~Dog();
    void doSomething();
};

class Cat : public Animal
{
public:
    Cat();
    ~Cat();
    void doSomething();
};
Animal* get_random_animal()
{
    static std::random_device rd;
    static std::mt19937 gen(rd());
    static std::uniform_int_distribution<> dis(1, 2);
    switch(dis(gen)) {
        case 1:
            return new Dog;
        case 2:
            return new Cat;
        default:
            throw std::runtime_error{"Not sure which animal."};
    }
}
class Person
{
public:
    Person(); 
    Person(Person&&) = delete; // person contains raw pointers, we must either delete or specify the move constructor
    Person(const Person&) = delete; // person contains raw pointers, we must either delete or specify the copy constructor
    Person& operator=(Person&&) = delete; // person contains raw pointers, we must either delete or specify the move assignment operator
    Person& operator=(const Person&) = delete; // person contains raw pointers, we must either delete or specify the copy assignment operator
    ~Person();
    void SomeMethod();
    Animal *ani;
};
Person::Person()
    : ani{get_random_animal()} // initialize with random animal
{
}
void Person::SomeMethod()
{
    ani->doSomething();
}
Person::~Person()
{
    delete ani; // Person does own animal
}

Dog::Dog()
{
    std::cout << "I've been created! Woof!" << std::endl;
}
Dog::~Dog()
{
    std::cout << "I've been destroyed! Woof!" << std::endl;
}
void Dog::doSomething()
{
    std::cout << "Woof" << std::endl;
}

Cat::Cat()
{
    std::cout << "I've been created! Meow!" << std::endl;
}
Cat::~Cat()
{
    std::cout << "I've been destroyed! Meow!" << std::endl;
}
void Cat::doSomething()
{
    std::cout << "Meow" << std::endl;
}
int main()
{
    Person will;
    will.SomeMethod();
    std::cout << "n More people with animals: n";
    std::vector<Person> people(10);
    return 0;
}

示例输出:

I've been created! Meow!
Meow
 More people with animals:
I've been created! Woof!
I've been created! Meow!
I've been created! Meow!
I've been created! Meow!
I've been created! Meow!
I've been created! Meow!
I've been created! Woof!
I've been created! Meow!
I've been created! Woof!
I've been created! Woof!
I've been destroyed! Woof!
I've been destroyed! Meow!
I've been destroyed! Meow!
I've been destroyed! Meow!
I've been destroyed! Meow!
I've been destroyed! Meow!
I've been destroyed! Woof!
I've been destroyed! Meow!
I've been destroyed! Woof!
I've been destroyed! Woof!
I've been destroyed! Meow!