附注:我大约一个月前开始在大学学习C ++。这是一项任务。我们现在正在凝视,不掌握许多高级概念。
tl; dr:让我们假设您有一个Book
。的Book
是的动态数组Pages*
。每个Page
可以是WrittenPage
或DrawnPage
。如果要打印全部,Pages
请使用virtual method
。如果您只想打印DrawnPages
或WrittenPages
,则必须在中进行某种过滤Book
。怎么做?现在,我发现您需要typeid
或某种其他方式来比较subtype
每个Page
。如果您想快速简单地进行操作,请查看@CantChooseUsernames接受的答案。对于我的问题,它工作得很好。如果您有更多专业知识,我想听听您对@nm的新答案的看法。如果您认为当前的答案给讨论带来了新的意义,请不要让当前接受的答案阻碍您发表评论或发表自己的看法。
原始问题:
我有一个MyObj类,它们是theseObj和ThatObj的超类。
Class TheseObj : public MyObj {
}
Class ThoseObj : public MyObj {
}
我还有另一个类,它包含一个带有指向MyObj实例的指针的std :: vector和一个非静态方法,在该方法中我只想列出theseObj:
Class MyClass {
private:
vector<MyObj*> vec;
public:
void listTheseObj() {
for each (myObj* obj in vec) {
if(typeid(*obj) == typeid(theseObj)) {
cout << *obj << endl;
}
}
}
}
所有运算符已经正确地过载了。
这很好用。现在的问题是,我还有很多地方需要做同样的事情,因此我需要一个可以接收GENERIC向量和TYPE类的模板方法,以便我可以执行以下操作:
listObjects(class_name_here, vec);
我设法创建了:
template <class T>
void listObjectsOfOneType(const type_info& class_name_here, const vector<T*>& vec) {
for each (T* obj in vec) {
if(typeid(*obj) == typeid(class_name_here)) {
cout << *obj << endl;
}
}
}
但我不确定:
希望我已经说清楚了,非常感谢您抽出宝贵的时间。
我可能会避免使用TypeID。尽管,我不确定您要实现的目标,但这是我所希望的:
#include <iostream>
#include <vector>
#include <typeinfo>
template <class T, class U>
void ListObjects(std::vector<U*> &vec)
{
for (U* obj : vec)
{
if (typeid(*obj) == typeid(T))
{
obj->Print();
std::cout<<"\n";
}
}
}
class Parent
{
public:
Parent() {std::cout<<"Parent Constructed\n";}
virtual ~Parent() {std::cout<<"Parent Destructed\n";}
virtual void Print(){std::cout<<"Parent\n";}
};
class Brother : public Parent
{
public:
Brother(){std::cout<<"Brother Constructed\n";}
virtual ~Brother(){std::cout<<"Brother Destructed\n";}
void Print() override {std::cout<<"Brother\n";}
};
class Sister : public Parent
{
public:
Sister(){std::cout<<"Sister Constructed\n";}
virtual ~Sister(){std::cout<<"Sister Destructed\n";}
void Print() override {std::cout<<"Sister\n";}
};
int main()
{
std::vector<Parent*> Objects;
Objects.push_back(new Parent());
Objects.push_back(new Brother());
Objects.push_back(new Sister());
std::cout<<"\n";
ListObjects<Parent>(Objects);
ListObjects<Brother>(Objects);
ListObjects<Sister>(Objects);
for (Parent* c : Objects)
{
delete c;
}
}
哪些打印:
修女
父级
姐姐
父母被毁
父母被毁
进程返回0(0x0)执行时间:0.066 s
很多评论告诉您不要使用TypeID,因为我们不确定您想要什么。 :
#include <iostream>
#include <vector>
#include <typeinfo>
template <class T>
void ListObjects(std::vector<T*> &vec)
{
for (T* obj : vec)
{
//TypeID isn't needed here because the virtual call will figure out which class's << operator to call.
//If each class has a print function, it can also figure out which class's print function to call..
//obj->Print(); //works too because each class has a print func.
std::cout<<*obj<<"\n"; //Works because each class has an overloaded << operator.
}
}
class Parent
{
protected:
virtual void Print(std::ostream& os) const {os<<"Parent\n";}
public:
Parent() {std::cout<<"Parent Constructed\n";}
virtual ~Parent() {std::cout<<"Parent Destructed\n";}
friend std::ostream& operator << (std::ostream &os, const Parent &p);
};
std::ostream& operator << (std::ostream &os, const Parent &p)
{
p.Print(os);
return os;
}
class Brother : public Parent
{
protected:
void Print(std::ostream& os) const override {os<<"Brother\n";}
public:
Brother(){std::cout<<"Brother Constructed\n";}
virtual ~Brother() {std::cout<<"Brother Destructed\n";}
};
class Sister : public Parent
{
protected:
void Print(std::ostream& os) const override {os<<"Sister\n";}
public:
Sister(){std::cout<<"Sister Constructed\n";}
virtual ~Sister(){std::cout<<"Sister Destructed\n";}
};
int main()
{
std::vector<Parent*> Objects;
Objects.push_back(new Parent());
Objects.push_back(new Brother());
Objects.push_back(new Sister());
std::cout<<"\n";
ListObjects(Objects); //NOTICE we all template types are now inferred.
for (Parent* c : Objects)
{
delete c;
}
}
在上面请注意,由于调用是虚拟的,因此代码的打印与使用TypeID的代码相同,并且该代码不再需要您在模板的花括号中键入任何内容。可以推断是因为我们不再需要使用typeid进行比较。
现在,由于您请求的是先前的代码,而模板是一个参数,因此:
template <class T, class U>
void ListObjects(std::vector<U*> &vec)
{
for (U* obj : vec)
{
if (typeid(*obj) == typeid(T))
{
obj->Print();
std::cout<<"\n";
}
}
}
会成为:
template<typename T>
void ListObjects(std::vector<T*> &vec, const std::type_info &type)
{
for (T* obj : vec)
{
if (typeid(*obj) == type)
{
std::cout<<*obj<<"\n";
}
}
}
并且您会像这样使用它: ListObjects(Objects, typeid(Child));
同样,所有这些都为您提供完全相同的结果。这完全取决于您的需求/用例。我们并不完全知道您要实现的目标。这些应该可以帮助您。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句