C++ 具有复制构造函数的多态性

C++ 具有复制构造函数的多态性,c++,polymorphism,copy-constructor,C++,Polymorphism,Copy Constructor,这是我使用的代码。我想知道我所做的是否正确和安全。通常它会编译,我做的测试是成功的。但由于这是我第一次使用dynamic\u cast和static\u cast,我想确保我没有遗漏任何东西 请检查一下: 我不会忘记删除任何指针(我真的不明白我的克隆方法是做什么的…) 如果我正确使用dynamic\u cast和static\u cast 没有比这更有效的方法了 但我主要关心的是我是否正确地实现了clone()方法 非常感谢 编辑 多亏了一些回答,我意识到我应该重新设计我的代码。所以我可以去

这是我使用的代码。我想知道我所做的是否正确和安全。通常它会编译,我做的测试是成功的。但由于这是我第一次使用
dynamic\u cast
static\u cast
,我想确保我没有遗漏任何东西

请检查一下:

  • 我不会忘记删除任何指针(我真的不明白我的克隆方法是做什么的…)
  • 如果我正确使用
    dynamic\u cast
    static\u cast
  • 没有比这更有效的方法了
但我主要关心的是我是否正确地实现了
clone()方法

非常感谢

编辑 多亏了一些回答,我意识到我应该重新设计我的代码。所以我可以去掉这段代码

.hpp文件:

#include <vector>

/*!Base class that will never be instantiate. It provides a way to create
 * GenericData with defferent type. */
class Data{
    public:
        /*!Constructor*/
        Data(std::string name):name_(name){}
        /*!Destructor, must be virtual*/
        virtual ~Data(){};

        /*!Method that allows a copy of the derived class*/
        virtual Data* clone() const = 0;

    protected:
        std::string name_;//!< Name of the (Generic)Data 

};

/*!Derived class that can contain any one value of any type and of name name_*/
template<typename Type>
class GenericData : public Data{
    public:
        /*!Constructor*/
        GenericData(std::string name, Type t): Data(name), t_(t){}
        /*!Destructor*/
        ~GenericData(){};

        /*!Method that implements*/
        GenericData<Type>* clone() const { return new GenericData<Type>(static_cast<GenericData<Type> const&>(*this) );}

        /*!Returns the value of the data*/
        Type const& get_val() const {return t_;}

    private:
        Type t_;//!< Value of the GenericData
};

/*!Contains a vector of Data*, can store diffrent GenericData*/
class Container{
    public:
        Container(){};
        Container(Container const& c){ 
            for(unsigned int i(0);i<c.data_.size();i++){
                data_.push_back((c.data_[i])->clone());
            }
        }
        ~Container(){
            for(unsigned int i(0);i<data_.size();i++){
                delete data_[i];
                data_[i] = NULL;
            }
        }

        /*!Add one GenericData<Type> of value t and named name*/
        template<typename Type>
            void set(std::string name, Type const& t){data_.push_back(new GenericData<Type>(name,t));}

        /*!Returns the value GenericData<Type>::t_ named name*/
        template<typename Type>
            Type get(std::string name) const;

    private:
        std::vector<Data*> data_;
};

template<typename Type>
void Container::set(std::string name, Type const& t){
    data_.push_back(new GenericData<Type>(name,t));
}

template<typename Type>
Type Container::get(std::string name) const {
    for(unsigned int i(0);i<data_.size();i++){
        if(data_[i]->get_name()==name){
            return dynamic_cast< GenericData<Type> *>(data_[i])->get_val();
        }
    }
    std::cerr<<"Container : get(string name) : no data with name "<<name<<std::endl;
    return 0;
}
#包括
/*!永远不会实例化的基类。它提供了一种创建
*具有不同类型的GenericData*/
类数据{
公众:
/*!构造函数*/
数据(std::string name):名称(name){
/*!析构函数,必须是虚拟的*/
虚拟~Data(){};
/*!方法,该方法允许派生类的副本*/
虚拟数据*clone()常量=0;
受保护的:
std::string name_;/!<(通用)数据的名称
};
/*!可以包含任何类型和名称的任何一个值的派生类_*/
模板
类GenericData:公共数据{
公众:
/*!构造函数*/
GenericData(std::string name,Type t):数据(name),t(t){
/*!析构函数*/
~GenericData(){};
/*!实现*/
GenericData*clone()常量{返回新的GenericData(static_cast(*this));}
/*!返回数据的值*/
键入const&get_val()const{return t}
私人:
键入GenericData的t_;/!<值
};
/*!包含数据向量*,可以存储不同的一般数据*/
类容器{
公众:
容器(){};
货柜(货柜构造及控制){
for(无符号整数i(0);iclone());
}
}
~Container(){
对于(无符号整数i(0);i(数据i[i])->get_val();
}
}

std::cerr无视您正在以一种可怕的方式重新实现
std::map
(您真的想允许将
GenericData
GenericData
存储在同一个容器中吗?),您的
克隆
方法甚至不应该编译,因为您正在调用
GenericData
的复制构造函数,而没有定义一个。这个简单易读的替代方法如何:

Data* clone() const {
    return new GenericData<Type>(name_, t_);
}
Data*clone()常量{
返回新的GenericData(名称,t);
}
这里您需要检查
dynamic\u cast
是否返回空指针。如果数据[i]不是
GenericData*
类型(或者不是指向从
GenericData
派生的某种类型的指针),将返回空指针

==========================================================
您还需要定义
Container::operator=
。如果不定义它,编译器将为您生成它,并且
vector
可能会被不正确地复制

==============================================================================


另外,我的建议是使用
std::shared_ptr
(如果使用C++98,则使用
boost::shared_ptr
)或
std::unique_ptr
而不是
Data*
来避免手动删除对象和相关的潜在内存泄漏。

我看不到
clone()
方法和
clone()中强制转换的意义
应该返回
数据*
。继承将做正确的事情。(除非为我阅读源代码已经很晚了)。@WhozCraig在大多数情况下,我会选择
克隆()<代码>返回>代码>数据*< /COD>,但C++支持共变返回,所以返回一个指向派生类的指针是合法的。@ JAMESCANZE是这样的,但是在这样做时,有一个原始的<代码>数据*P<代码>,调用<代码> p> >克隆()/代码>将工作?(即调用只在返回类型中不同的适当的派生克隆)?如果是这样的话,我需要去获取我的标准,并开始阅读它是如何连接起来的(好像我不会像一开始所展示的那样编写代码).如果你知道标准即兴的协变部分,请告诉我,如果你不知道,没什么大不了的,我会找到它。@WhozCraig是的。协变返回就是这个意思。在C++11中,它在§10.3/7中(但它从C++98开始就存在了)。默认的复制ctor既不是
delete
ed,也不是
private
-ized。它应该编译(假设
set
的redecl等所有其他错误都已修复)。我对数据访问有点困惑。(例如,我看不到要点)。“从未听说过std::map”-在编写下一行代码之前,您应该先了解它。然后再了解
boost::any
(但不要将您的应用程序设计建立在它的基础上!)@n.m.我完全改变了我的应用程序设计。因为您的评论和LumpN的评论,“您真的想允许将GenericData和GenericData存储在同一个容器中吗?”.所以我不再需要我的
容器
类了。。。
GenericData<Type>* clone() const{
    return new GenericData<Type>(static_cast<GenericData<Type> const&>(*this) );
}
    if(data_[i]->get_name()==name){
        return dynamic_cast< GenericData<Type> *>(data_[i])->get_val();
    }