动态转换派生类的需求:寻找替代方法 [英] A need for dynamic cast of a derived class: looking for an alternative approach

查看:58
本文介绍了动态转换派生类的需求:寻找替代方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我以这种简单的形式提出问题:

I present my question in this simple form:

class animal {
public:
    animal() {
        _name="animal";
    }

    virtual void makenoise(){
        cout<<_name<<endl;
    }

    string get_name(){
        return _name;
    }

protected:
    string _name;
};

class cat : public animal {
public:
    cat() {
        this->_name="cat";
    }
};

class dog : public animal {
public:
    dog() {
        this->_name = "dog";
    }
};

我想将所有动物类型一起存储在一个容器中,例如:

I want to store all animal types together in a single container such as:

vector<animal*> container;
barnyard.push_back(new animal());
barnyard.push_back(new dog());
barnyard.push_back(new cat());

在代码的某个时刻,我需要将dog对象转换为cat对象.我从此转换中所需要做的就是设置一个新的dog对象,并以与cat对应的对象相同的索引号替换它.据我了解,在这种情况下dynamic_cast无效,并且基于将C ++强制转换为派生类,提到这种转换不是一个好习惯.由于模型中的猫和狗具有不同的行为特性,因此我不想将它们的定义放到动物模型中.另一方面,将它们分别存储在不同的向量中将很难处理.有什么建议吗?

At some point in my code, I need to convert a dog object into a cat object. And all I need from this converting is to set up a fresh dog object and replace it at the same index number as a cat counterpart was located. As I understood, dynamic_cast wouldn't work in this case and based on C++ cast to derived class, it's mentioned that such a conversion is not a good practice. Since cat and dog in my model have distinct behavioral properties, I don't want to put their definitions into the animal model. On the other hand, storing them separately in different vectors would be difficult to handle. Any suggestions?

推荐答案

您说:

我需要将狗对象转换为猫对象.

I need to convert a dog object into a cat object.

但是然后:

通过这种转换,我所需要做的就是设置一个新的dog对象,并以与cat对应的对象相同的索引号替换它.

And all I need from this converting is to set up a fresh dog object and replace it at the same index number as a cat counterpart was located.

您需要转换还是替换它??这是完全不同的操作.

Do you need to convert it or replace it?? That's a completely different operation.

要进行转换,您需要设置一个将狗带回猫的函数:

To convert you need to setup a function that will take a dog and return a cat:

auto convertDogToCat(Dog const& dog) -> Cat {
    auto cat = Cat{};

    // fill cat's member using dog's values...

    return cat; 
}

但是要替换为新的,只需重新分配:

But to replace simply reassign with a new one:

//      v--- a cat is currently there
barnyard[ii] = new Dog{};
//           ^--- we replace the old pointer
//                with one that points to a dog.

但这会造成内存泄漏,要消除此泄漏,只需使用std::unique_ptr:

But that creates a memory leak, to remove the leak, simply use std::unique_ptr:

#include <memory> // for std::unique_ptr

// The base class need a virtual destructor
class animal {
public:
    virtual ~animal() = default;

    // other members...
};

std::vector<std::unique_ptr<animal>> barnyard;
barnyard.emplace_back(std::make_unique<animal>());
barnyard.emplace_back(std::make_unique<dog>());
barnyard.emplace_back(std::make_unique<cat>());

barnyard[ii] = std::make_unique<Dog>();

这篇关于动态转换派生类的需求:寻找替代方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆