我有一个名为Alma
的(父)类,带有(虚拟)函数Getwidth()
和两个派生类Alma
,名为Birs
(具有特殊函数Getheight()
)和Citrom
(具有特殊函数Getdepth()
)。我想声明一个名为Attila
的对象,它的类型是Birs
还是Citrom
,这取决于bool
。稍后,我想使用通用函数Getwidth()
和特殊函数(取决于前面提到的bool
)。
我的(不工作的)代码:
/*...*/
/*Classes*/
class Alma{
public: virtual int Getwidth() = 0;
/*ect...*/
}
class Birs: public Alma{
int Getwidth(){return 1;}
public: int Getheight(){return 2;}
/*ect...*/
}
class Citrom: public Alma{
int Getwidth(){return 3;}
public: int Getdepth(){return 4;}
/*ect...*/
}
/*...*/
/*Using them*/
void Useobjects(){
/*Create object depending on bool*/
if(b00lvar){
Birs Andor();
std::cout<<Andor.Getwidth()<<" "<<Andor.Getheight()<<std::endl;
}else{
Citrom Andor();
std::cout<<Andor.Getwidth()<<" "<<Andor.Getdepth()<<std::endl;
}
/*Using the common part of object*/
std::cout<<Andor.Getwidth()<<std::endl;
/*Using the special part of object*/
if(b00lvar){
std::cout<<Andor.Getheight()<<std::endl;
}else{
std::cout<<Andor.Getdepth()<<std::endl;
}
/*ect...*/
}
发布于 2016-03-25 19:15:17
这是多态对象处理的一个典型案例。只要确保你熟悉这个概念以及指针和引用即可。
你需要的东西看起来像这样:
Alma* Andor;
if(b00lvar){
Andor = new Birs();
std::cout<<Andor->Getwidth()<<" "<<Andor->Getheight()<<std::endl;
}else{
Andor = new Citrom();
std::cout<<Andor->Getwidth()<<" "<<Andor->Getdepth()<<std::endl;
}
接下来,使用dynamic_cast
返回派生类型,最后,当然不要忘记删除对象。但首先要了解这些概念。
发布于 2016-03-25 19:06:26
您不能定义类型为this或that的单个对象,这取决于其他内容。C++不是这样工作的。C++是一种静态类型的语言。这意味着每个对象的类型都是在编译时确定的。其他语言,如Perl或Javascript,是动态类型的,其中对象的类型是在运行时确定的,单个对象可以在某一时刻是一件事,在另一件事上是另一件事。
但是C++不是这样工作的。
要做一些像你试图做的事情,你必须重构代码,并使用虚拟超类。如下所示:
void UseObject(Alma &andor)
{
/*Using the common part of object*/
std::cout<<andor.Getwidth()<<std::endl;
/*Using the special part of object*/
/* This part is your homework assignment */
}
void Useobjects(){
/*Create object depending on bool*/
if(b00lvar){
Birs andor;
std::cout<<Andor.Getwidth()<<" "<<Andor.Getheight()<<std::endl;
UseObject(andor);
}else{
Citrom andor;
std::cout<<Andor.Getwidth()<<" "<<Andor.Getdepth()<<std::endl;
UseObject(andor);
}
}
另一种方法是使用两个指针,在本例中将两个指针传递给UseObject()
。两个指针中的一个将始终是nullptr
,另一个是指向实例化对象的指针,并将UseObject()
编码为处理传入的任何对象。
这也是可能的,但会导致丑陋的代码,如果我是一名教授C++的教师,我会记下任何提交了这样做的代码的人。
发布于 2016-03-25 19:19:07
您可以使用指针语义来实现这一点,使用dynamic_cast
来实现类型自省。我扩展了您的示例,以展示我将如何处理它。
这是Demo
#include <iostream>
#include <memory>
using namespace std;
class Alma{
public:
virtual int Getwidth() = 0;
};
class Birs: public Alma{
public:
int Getwidth() { return 1; }
int Getheight() { return 2; }
};
class Citrom: public Alma{
public:
int Getwidth() { return 3; }
int Getdepth() { return 4; }
};
shared_ptr<Alma> make_attila(bool birs)
{
if (birs)
return make_shared<Birs>();
else
return make_shared<Citrom>();
}
void test_attila(shared_ptr<Alma> attila)
{
cout << "width: " << attila->Getwidth() << "\n";
if (auto as_birs = dynamic_pointer_cast<Birs>(attila))
cout << "height: " << as_birs->Getheight() << "\n";
else if (auto as_citrom = dynamic_pointer_cast<Citrom>(attila))
cout << "depth: " << as_citrom->Getdepth() << "\n";
}
int main() {
shared_ptr<Alma> attila = make_attila(true);
test_attila(attila);
attila = make_attila(false);
test_attila(attila);
return 0;
}
下一步是将make_attila
作为模板函数,将派生类作为模板参数,而不是布尔值。
template <class Derived>
shared_ptr<Alma> make_attila()
{
return make_shared<Derived>();
}
https://stackoverflow.com/questions/36218655
复制相似问题