C ++继承 - super.method()Java等价物

时间:2014-05-08 01:38:45

标签: c++ inheritance

我有一个名为Animal的超类,它有一个名为create的方法:

static Animal* Animal::create(const std::string& name)
{
Animal* newAnimal = new Animal();
newAnimal ->name = name;
return newAnimal;

}

现在我有一个名为Dog的子类。我想覆盖create中的Animal方法,但要避免复制并粘贴已经存在的代码......我基本上想要这个:

static Dog* Dog::create(const std::string& name)
{
Dog* newDog = Animal::create(name); // This is the line that I have trouble with.
newDog->type="dog";
}

正如我上面提到的,我注意到C ++没有进行自动转换 - 我来自Java背景......

无论如何,我想知道这是否是一种可接受的方法来解决它并且不会导致更多的头痛:

  Dog *newDog  = static_cast<Dog *>(Animal::create(name));

附加说明: 所以在阅读完所有评论和解决方案之后,我想每个人都建议使用构造函数。但是想象一下你不允许修改Animal类的情况,它有一个create方法,你想扩展该方法。也许更合适的方式是:是否可以扩展超类创建方法?让我知道如果我完全离开 - 我对c ++非常非常新,所以也许这个问题在c ++的观点上是无意义的......

2 个答案:

答案 0 :(得分:3)

我只使用构造函数和多态。

class Animal
{
  const std::string name;
public:
  explicit Animal(const std::string &name) : name(name) {}
  virtual ~Animal() {}
  virtual std::string type() const = 0;
};

class Dog : public Animal
{
public:
  explicit Dog(const std::string &name) : Animal(name) {}
  virtual std::string type() const { return "dog"; }
};

如果你因为某种原因真的不喜欢多态,那么在type中添加Animal数据成员,并在Dog::Dog(狗构造函数)中分配给它


我不认为你可以做你想做的事而不改变Animal的创建方式。这就是原因。

首先,这是Animal::create的作用。

  1. 在堆
  2. 上分配sizeof Animal个字节
  3. 使用分配的内存块调用Animal的默认构造函数。
  4. 设置name字段。
  5. 返回指向Animal对象
  6. 的指针

    以下是Dog::create函数需要执行的操作:

    1. 在堆
    2. 上分配sizeof Dog个字节
    3. 初始化新Animal对象的Dog部分。我想您正在尝试重用Animal::create函数吗?
    4. 设置type字段
    5. 将指针返回Dog对象
    6. 问题在于Dog::create的第2步。由于Animal::create分配了自己的内存并且您无法传入指向Dog的指针,因此无法让Animal::create对您在步骤1中分配的内存进行操作

      这就是说,取决于Animal的内部结构,特别是如果它是可复制的,你可以能够按照以下方式破解它,但我不确定它是否会工作甚至定义明确

      static Dog * Dog::create(static Dog* Dog::create(const std::string& name)
      {
        Animal *animalTmp = Animal::create(name);
        Dog* newDog = new Dog();   // note that Animal::Animal() c-tor is probably called
        *newDog = *animalTmp;      // you have to be careful about which `operator=` is called here
        delete animalTmp;
        newDog->type="dog";
        return newDog;
      }
      

      这完全不可维护,丑陋如同地狱,非常脆弱,以及可怕的想法。

答案 1 :(得分:1)

通常解决方案是使用构造函数:

#include <string>
class animal {
public: 
    animal();
    animal(std::string name, std::string type);
    virtual ~animal();
private:
    std::string name_;
    std::string type_;
};
animal::animal() 
    :name_("unnamed"), type_("unknown") 
    {}
animal::animal(std::string name, std::string type) 
    :name_(std::move(name)), 
    type_(std::move(type)) 
    {}
animal::~animal() {}

然后:

class dog : public animal{
public: 
    dog();
    dog (std::string name);
    virtual ~dog ();
};
dog::dog() :animal("","dog") {} //delegate to the animal default constructor
dog::dog(std::string name) :animal(std::move(name), "dog") {} //delegate again
dog::~dog() {}

并且更容易使用:

int main() {
    dog fido("fido"); //creates a dog on the stack, _very fast_
};