Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/152.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ C++;模板的类(非对象)参数_C++_Class_Templates_Vector_Smart Pointers - Fatal编程技术网

C++ C++;模板的类(非对象)参数

C++ C++;模板的类(非对象)参数,c++,class,templates,vector,smart-pointers,C++,Class,Templates,Vector,Smart Pointers,我有一些派生类,这些派生类继承自具有虚函数的基类。我使用智能指针(shared_ptr)来创建对象,因为我希望将对象附加到向量中。但我注意到我的代码在处理对象以完成某些任务时是重复的,所以我认为模板可以作为改进代码的解决方案。 这是我迄今为止的尝试(不是确切的代码,简化): 类基{ 公众: 虚拟~Base(){} 虚空显示_消息()=0; }; DerivedA类:公共基础{ DerivedA(){} }; B类:公共基{ DerivedB(){} }; //模板- // 模板 类指针{ 私人:

我有一些派生类,这些派生类继承自具有虚函数的基类。我使用智能指针(shared_ptr)来创建对象,因为我希望将对象附加到向量中。但我注意到我的代码在处理对象以完成某些任务时是重复的,所以我认为模板可以作为改进代码的解决方案。 这是我迄今为止的尝试(不是确切的代码,简化):

类基{
公众:
虚拟~Base(){}
虚空显示_消息()=0;
};
DerivedA类:公共基础{
DerivedA(){}
};
B类:公共基{
DerivedB(){}
};
//模板-
//
模板
类指针{
私人:
矢量对象矢量;
//迭代器
T1 sp_碱基;
公众:
手动指示器(常数T1和sp){
sp_base=sp;//设置智能指针
}
//某些函数
//这就是我需要弄明白的
void AddToVector(){
push_back(sp_base(新的“派生类”);
}
};

这里的问题是AddToVector函数。为了添加一个对象的元素,我必须向后推(“智能指针”(新的“类”);。如何让模板接受类(而不是对象)并将其实现为push_back()函数?

使函数也成为模板:

template<typename T2>
void AddToVector(){
    ObjectVector.push_back(smart(new T2));
}
模板
void AddToVector(){
ObjectVector.push_back(智能(新T2));
}

我假设您打算在
push_back
中有一个智能指针,比您的成员变量
sp_base

还使函数成为模板:

template<typename T2>
void AddToVector(){
    ObjectVector.push_back(smart(new T2));
}
模板
void AddToVector(){
ObjectVector.push_back(智能(新T2));
}

我假设您打算在
push_back
中有一个智能指针,而不是您的成员变量
sp_base
您试图将一个对象用作一个类,但这不会起作用(除非该对象有一个返回正确对象的
操作符()
,但我离题了)

请尝试:

void AddToVector(){
    ObjectVector.push_back(T1(sp_base));
}

这将创建一个新对象,并调用新对象的复制构造函数,并将
sp_base
传递给它。因此,本质上创建一个
sp_base

的副本,您试图将一个对象用作一个类,但这不会起作用(除非该对象有一个返回正确对象的
操作符()
,但我离题了)

请尝试:

void AddToVector(){
    ObjectVector.push_back(T1(sp_base));
}

这将创建一个新对象,并调用新对象的复制构造函数,并将
sp_base
传递给它。因此本质上,创建一个
sp_base

的副本这是一个具有挑战性的副本-为什么?由于模板是基于C++模板中的一种预处理步骤,通过动态地构造基于模板参数的类的变体。 <>代码>代码> SyddYPPT/<代码>和代码> SyddypTr> /Cord>,它们之间没有任何关系,因为在C++中,模板本质上使它们像2个单独的类声明-不相关类型。p> 它们包含的指针都是基类的后代,但共享的ptr本身也可能是
向量
Foo
。无论
DerivedA
DerivedB
从单个基类继承,它们的模板生成的类都不会继承

也就是说,您确实有一些灵活性:如果您在类的接口中放置工厂函数,如下所示:

class DerivedA : public Base{
    public:
    static shared_ptr<DerivedA> construct{
        return shared_ptr<DerivedA>(new DerivedA());
    };
};

....similar for DerivedB
template<typename T>
class HandleInstances{
  private:            

     vector<shared_ptr<T> > ObjectVector;

  public:

    //this is what i need to figure out
    void AddToVector(){
         ObjectVector.push_back(T::construct());
    }
};
class-DerivedA:公共基础{
公众:
静态共享ptr构造{
返回shared_ptr(new DerivedA());
};
};
……与DerivedB类似
然后你可以这样做:

class DerivedA : public Base{
    public:
    static shared_ptr<DerivedA> construct{
        return shared_ptr<DerivedA>(new DerivedA());
    };
};

....similar for DerivedB
template<typename T>
class HandleInstances{
  private:            

     vector<shared_ptr<T> > ObjectVector;

  public:

    //this is what i need to figure out
    void AddToVector(){
         ObjectVector.push_back(T::construct());
    }
};
模板
类指针{
私人:
矢量对象矢量;
公众:
//这就是我需要弄明白的
void AddToVector(){
push_back(T::construct());
}
};
你应该没事。您所做的是为每个类提供一个函数,以弥补类本身无法存储以在以后生成对象的事实。注意:

  • HandleInstances中的模板参数是基类型,而不是共享类型
  • Construct
    在DerivedA和DerivedB中返回不同的类型
  • Base
    没有
    construct
    的声明-因为这些函数不返回兼容的类型,所以它们不会从Base继承
  • 你仍然不能在你的ObjectVector中混合和匹配类型,如果这是你所希望的——但是你无论如何也不可能做到。(好处:如果您使用更多类型来包装您的类型并处理此问题,则这是可能的:请参阅

  • 这是一个挑战性的问题-为什么?因为模板是C++中的一种预处理步骤,通过动态地构造基于模板参数的类的变体。 <>代码>代码> SyddYPPT/<代码>和代码> SyddypTr> /Cord>,它们之间没有任何关系,因为在C++中,模板本质上使它们像2个单独的类声明-不相关类型。 它们包含的指针都是基类的后代,但共享的ptr本身也可能是一个

    Vector
    和一个
    Foo
    。不管
    DerivedA
    DerivedB
    继承自一个基类,它们的模板生成的类都不会继承

    也就是说,您确实有一些灵活性:如果您在类的接口中放置工厂函数,如下所示:

    class DerivedA : public Base{
        public:
        static shared_ptr<DerivedA> construct{
            return shared_ptr<DerivedA>(new DerivedA());
        };
    };
    
    ....similar for DerivedB
    
    template<typename T>
    class HandleInstances{
      private:            
    
         vector<shared_ptr<T> > ObjectVector;
    
      public:
    
        //this is what i need to figure out
        void AddToVector(){
             ObjectVector.push_back(T::construct());
        }
    };
    
    class-DerivedA:公共基础{
    公众:
    静态共享ptr构造{
    返回shared_ptr(new DerivedA());
    };
    };
    ……与DerivedB类似
    
    然后你可以这样做:

    class DerivedA : public Base{
        public:
        static shared_ptr<DerivedA> construct{
            return shared_ptr<DerivedA>(new DerivedA());
        };
    };
    
    ....similar for DerivedB
    
    template<typename T>
    class HandleInstances{
      private:            
    
         vector<shared_ptr<T> > ObjectVector;
    
      public:
    
        //this is what i need to figure out
        void AddToVector(){
             ObjectVector.push_back(T::construct());
        }
    };
    
    模板
    类指针{
    私人:
    矢量对象矢量;
    公众:
    //这就是我需要弄明白的
    void AddToVector(){
    push_back(T::construct());
    }
    }