【问题标题】:How to change a class to another class which derive from the same base class?如何将一个类更改为派生自同一个基类的另一个类?
【发布时间】:2020-07-28 07:08:08
【问题描述】:

我有一个名为 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 *”类型的实体

受保护的成员“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 = Dog *"

【问题讨论】:

  • 您不能在运行时更改类。您要解决的真正问题是什么?
  • @Yksisarvinen 如果狗的体重小于 40 就会变成猫,如果猫的体重超过 40 就会变成狗
  • 您可以将狗转换为猫,但它不再是狗,因此它不是同一个对象,至少在 C++ 世界中(可以将狗转换为猫)跨度>
  • 您希望调用代码的外观如何? animal_change 可以返回不同类型的新对象
  • @No_Name 听起来您希望工厂函数根据传递的权重值将DogCat 对象作为Animal* 返回

标签: c++ class oop inheritance polymorphism


【解决方案1】:

通常,您不能将对象分配给不同的类之一——这就是静态类型系统的意义所在。为了“改变”多态对象的动态类型,客户端代码可以像这样创建另一个:

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{};
  }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-03-18
    • 2021-11-19
    • 1970-01-01
    • 1970-01-01
    • 2016-12-12
    相关资源
    最近更新 更多