C++ 在派生类C++;
我有一些不同的对象,它们的类型都是C++ 在派生类C++;,c++,virtual,base-class,C++,Virtual,Base Class,我有一些不同的对象,它们的类型都是Zoo,它们有一个成员变量Collection=vector。我有一个动物园的例子,所有的元素都是动物,一个所有的元素都是鸟,还有一个所有的元素都是蝙蝠。鸟类和蝙蝠都起源于动物 我希望有一个方法fly(),我可以调用所有的鸟类和蝙蝠,但我不确定最好的方法是什么。当我在我的鸟类/蝙蝠动物园中循环时,我应该投下吗?像这样: Bird thisBird = static_cast<Bird>(Collection[i]); thisBird.fly();
Zoo
,它们有一个成员变量Collection=vector
。我有一个动物园的例子,所有的元素都是动物,一个所有的元素都是鸟,还有一个所有的元素都是蝙蝠。鸟类和蝙蝠都起源于动物
我希望有一个方法fly()
,我可以调用所有的鸟类和蝙蝠,但我不确定最好的方法是什么。当我在我的鸟类/蝙蝠动物园中循环时,我应该投下吗?像这样:
Bird thisBird = static_cast<Bird>(Collection[i]);
thisBird.fly();
Bird thisBird=static_cast(集合[i]);
这只鸟;
。。。或者我可以在Animal上有一个虚拟函数,它只在派生自它的类上实现
想法,以及为什么它们是“好代码”的理由,欢迎 并非所有动物都能飞,因此没有必要为了一般目的而尝试执行特定行为(即所有动物之间不常见的行为)。如果你有一个动物类(或它们的派生类)的集合,它的目的是允许它们做一个共同的行为(每个派生类的实现方式不同)
你可以实现一个
flyible
接口(即抽象类),并只对真正会飞的动物进行扩展。而不仅仅是将它们保存在为这些动物指定的另一个集合中(即) 您可能不希望像Bird
和Bat
这样的层次结构起源于Animal
,而不需要fly()
方法,这些方法是从低级类中声明的。这样一来,您就失去了统一层次结构的意义
您可以执行以下任一操作:
class Animal {
virtual bool canFly() { return false; }
virtual void fly() {throw Exception( "Sorry babe, I don't fly"); }
}
并在Bird
和Bat
中覆盖fly
这将导致为狗和猫实现方法fly()。因此,也许您可以创建新的类传单,它将声明此方法:
class Flyer : public Animal {
virtual void fly() = 0;
}
class Bat : public Flyer {}
class Bird : public Flyer {}
这与更详细的生物学分类不一致,如爬行动物、哺乳动物
另一个技巧可能是提出类似于move()
的方法,dog将其实现为run()
,bird实现为fly()
,所有这些都具有统一的接口
另一件事是,我认为询问狗是否会飞是一个有效的问题,所以我认为像dog.canFly()
这样的方法应该在您的代码中实现,作为动物的一部分
考虑到所有这些因素,我认为:
// Your base animal
class Animal {
virtual bool canFly() {return false;}
};
// Any animal that could fly, just abstract class
class Flyer {
virtual void fly() = 0;
}
// Ants, flies etc.; real biological hierarchy
class Insect : public Animal {}
class Mammals : public Animals {}
class Birds : public Animals {}
// And now flying bird :
class Bird : public Birds, public Flyer {
virtual bool canFly() {return true; }
virtual void fly() {...}
}
// And flying insect
class Fly : public Insect, public Flyer {
virtual bool canFly() {return true; }
virtual void fly() {...}
}
然后你就可以这样做了(基于我恐怕你必须使用指针):
但是,如果您将动物和鸟类的传单作为鸟类和传单的一部分,则:
class Animal {
public:
virtual bool canFly() const {return false;}
};
class Flyer : virtual Animal {
public:
virtual bool canFly() const {return true;}
virtual void fly() {cout << "Flying" << endl; }
};
class Bird : virtual public Birds, virtual public Flyer {
};
// Warning 1 warning C4250: 'Bird' : inherits 'Flyer::Flyer::canFly' via dominance
请注意,传单
仍然很重要,因为昆虫
提供的苍蝇
哦,是的,动物
可能具有虚拟功能:
virtual void move(){}
virtual void fly(){}
当你命令狗飞的时候,它什么也不做。当你命令一只鸟移动时,它也可以调用fly()
为飞行的动物正确定义fly()
,并且
collection[i]->fly()
将做正确的事情。这样你的代码就简单了
但要做到这一点,您的集合必须收集指向动物的指针,而不仅仅是动物对象。
例如:
#include <vector>
#include <memory>
#include <iostream>
using namespace std;
struct Animal{virtual void fly(){}};
struct Bird:public Animal{void fly(){cout<<"fly\n";}};
int main()
{
vector<unique_ptr<Animal>> Colection(1);
Colection[0].reset( new Bird );
Colection.push_back(unique_ptr<Animal>(new Bird) );
Colection.push_back(unique_ptr<Animal>(new Animal) );
Colection[0]->fly();
Colection[1]->fly();
Colection[2]->fly();
}
#包括
#包括
#包括
使用名称空间std;
结构动物{virtualvoid fly(){};
结构鸟:公共动物{void fly(){coutfly();
collection[2]->fly();
}
阅读其他答案,我可以建议您执行以下操作
struct Animal {virtual bool fly(){return false; }};
struct Bird:public Animal{bool fly(){cout<<"fly\n";return true;}};
struct Animal{virtual bool fly(){return false;};
struct Bird:public Animal{bool fly(){coutYou正在将可能按值多态使用的对象放在一个容器中。每个动物园的集合向量中只包含相同类型的动物(通用、鸟类或蝙蝠),不过..如果不是通过铸造,你对我应该怎么做有什么建议吗?…啊-应该是收藏。已编辑以更正this@tiswas:这不是重点。如果你有一个向量
,你把一只鸟
推进去,那只鸟会被切成薄片,而你的向量只会持有一只不能再移动的动物
r回到Bird
。仔细阅读切片问题;解决方案是在向量中保留(智能?)指针。我明白了。那么回到我的问题-我应该怎么做?这不要求每个动物园都有不同的类型吗,因为它们的成员变量集合有不同的类型(向量与向量相反)?这在很大程度上取决于你的动物园在你的程序中扮演什么角色。我相信如果你设计正确,在这种飞行环境中,你将只有一种动物园类型。投票者会从阴影中走出来解释吗?嗯,我喜欢这个声音,但是@Jon提到:“如果你有一个向量,你把一只鸟推进去,那只鸟会被吃掉。”切片后,你的向量将只容纳一个不能再扔回鸟身上的动物。@tiswas说实话,我一直在使用指针,这些都没有问题。只是为了好玩,实现复制构造函数,看看它被调用了多少次。:@Vyktor似乎有意义将canFly默认实现返回true到Flyer中(默认情况下,传单可以飞行!)@Ricibob试图将其添加到answer中,但如果没有一个好的答案,它会变得越来越复杂。这就是我的观点“没有..,它会越来越复杂”。为什么不将virtual void fly(){}添加到基类中?为什么添加canFly()会更好?这对我来说似乎是最简单的赌注,虽然我没有使用C++11,所以我想我只需要向量集合;
virtual void move(){}
virtual void fly(){}
#include <vector>
#include <memory>
#include <iostream>
using namespace std;
struct Animal{virtual void fly(){}};
struct Bird:public Animal{void fly(){cout<<"fly\n";}};
int main()
{
vector<unique_ptr<Animal>> Colection(1);
Colection[0].reset( new Bird );
Colection.push_back(unique_ptr<Animal>(new Bird) );
Colection.push_back(unique_ptr<Animal>(new Animal) );
Colection[0]->fly();
Colection[1]->fly();
Colection[2]->fly();
}
struct Animal {virtual bool fly(){return false; }};
struct Bird:public Animal{bool fly(){cout<<"fly\n";return true;}};