Как изменить класс на другой класс, производный от того же базового класса? - PullRequest
0 голосов
/ 15 апреля 2020

У меня есть базовый класс с именем Animal:

class Animal {

protected:    
    std::string name;
    int age;
    int weight;  
public:
    Animal(const std::string& _name, int _age, int _weight):name(_name),age(_age),weight(_weight) {};
    virtual void animal_cange(Animal*) = 0;
};

, и из класса Animal происходит два подкласса

class Dog : public Animal {

public:  
    Dog(const std::string& _name, int _age, int _weight) :Animal(_name, _age, _weight) {};
    void animal_cange(Animal* poot) override {

        this = new Cat(poot->name,poot->age,poot->weight);   
    }    
};

, и это

class Cat : public Animal {

public:

    Cat(const std::string& _name, int _age, int _weight) :Animal(_name, _age, _weight) {};

    void animal_cange(Animal* poot) override {

        this = new Dog(name, age, weight);   
    }   
};

, которое я сделал виртуальная функция в базовом классе, вызванная virtual void animal_cange(Animal*) = 0;, которая должна заменить объект Dog на объект Cat, если он вызывается с уже существующим именем объекта, значением возраста и веса и наоборот, но всегда выдает ошибку, например:

присвоение 'this' (анахронизм)

значение типа "Cat *" не может быть присвоено сущности типа "Dog *"

protected member "Animal :: name "(объявлено в строке 12) не доступно через указатель или объект

Я также пытался без animal_change быть виртуальной функцией, подобной этой:

class Animal {

protected:    
    std::string name;
    int age;
    int weight;
public:
    Animal(const std::string& _name, int _age, int _weight):name(_name),age(_age),weight(_weight) {};
};



class Dog : public Animal {
public:    
    Dog(const std::string& _name, int _age, int _weight) :Animal(_name, _age, _weight) {};
    void animal_cange()  {

        this = new Cat(this->name,this->age,this->weight);
   }
};

class Cat : public Animal {

public:

    Cat(const std::string& _name, int _age, int _weight) :Animal(_name, _age, _weight) {};

    void animal_cange()  {

        *this = new Dog(name, age, weight);
    }
};

И ошибки, которые я получаю:

this = new Cat(this->name,this->age,this->weight);: «назначение 'this' (анахронизм)" и ошибка объекта

"ни один оператор не соответствует этим типам операндов: Cat = Собака * "

1 Ответ

1 голос
/ 17 апреля 2020

Как правило, вы не можете присвоить объект другому классу - вот что такое система типов stati c. Чтобы «изменить» тип динамического c объекта polymorphi c, клиентский код может создать другой объект, подобный следующему:

Animal* animal = new Dog{}; // actually you should use smart pointers
if (want_to_change) {
  delete animal; // prevents a memory leak; smart pointers perform it automatically
  animal = new Cat{};
}

Если вы хотите, чтобы фактический выбор типа животного происходил во время инициализации, подумайте используя фабрику:

class Factory {
public:
  // may be static if uses no state, than you can just write a free function
  Animal* produce(/* some parameters */) const;
};

Animal* Factory::produce(/* some parameters */) const {
  if (should_be_cat(/* depending on the parameters */)) {
    return new Cat{};
  } else {
    return new Dog{};
  }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...