如何在C ++中将类(不是对象)作为参数传递

dR_

附注:我大约一个月前开始在大学学习C ++。这是一项任务。我们现在正在凝视,不掌握许多高级概念。

tl; dr:让我们假设您有一个BookBook是的动态数组Pages*每个Page可以是WrittenPageDrawnPage如果要打印全部,Pages请使用virtual method如果您只想打印DrawnPagesWrittenPages,则必须在中进行某种过滤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;
        }
    }
}

但我不确定:

  1. 如果模板方法正确
  2. 我怎么称呼它

希望我已经说清楚了,非常感谢您抽出宝贵的时间。

布兰登

我可能会避免使用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] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

如何在Java中将类作为参数传递?

如何在Swift中将类作为参数传递?

如何在java中将类作为参数传递

如何在Java中将对象数组作为参数传递

如何在WSK(Openwhisk)中将JSON对象作为参数传递

如何在Javascript中将对象的方法作为参数传递

如何在Java中将类对象作为变量传递

如何在C#方法中将Json对象作为参数传递

如何在C ++中将多个对象作为参数传递给函数

在C ++中将内部模板类作为模板参数传递

在C ++中将模板类引用作为参数传递

在 C# 中将类的实例作为参数传递

如何在C中将连续数组作为参数传递?

如何在C ++中将类型作为参数传递?

如何在C ++中将函数作为参数传递?

如何在C中将函数作为参数传递?

如何在Rcpp / C ++中将函数作为参数传递?

如何在C ++中将文件作为参数传递?

作为参数传递时如何读取类对象/函数?

如何将对象/类作为函数的参数传递

将Cython类对象作为参数传递给C函数

在C ++中将派生类对象传递给具有基类参数的函数时,为什么要传递引用而不是值?

如何在模板类方法中将方法指针作为参数传递

如何在Java中将泛型列表类作为参数传递给泛型方法?

如何在 selenium 中将输入参数作为测试类名传递?

如何在 URI 行中将对象作为查询参数传递?

如何在python中将字典对象作为参数传递给函数

如何在子进程python中将pdf对象作为参数传递?

如何在javascript函数中将JSON对象作为函数参数传递?