我有一个名为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 ++的观点上是无意义的......
答案 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
的作用。
sizeof Animal
个字节
Animal
的默认构造函数。name
字段。Animal
对象以下是Dog::create
函数需要执行的操作:
sizeof Dog
个字节
Animal
对象的Dog
部分。我想您正在尝试重用Animal::create
函数吗?type
字段Dog
对象问题在于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_
};