类型铸造问题

时间:2012-08-22 20:08:23

标签: c++ casting virtual dynamic-cast

假设您有基类Unix_tree,派生Unix_tree_type1Unix_tree_type2等等。为什么我无法将Unix_tree投射到Unix_tree_type ......?有没有办法进行这样的演员表演?派生类包含抽象方法的实现,其目标是以不同方式打印基类中包含的数据。感谢。

class Unix_tree
    {
    public:
        Unix_tree () 
        {
            tree_it.tree = &tree;
        }

        Unix_tree(const Unix_tree& utree) : num_of_files(utree.num_of_files), tree(utree.tree), tree_it(utree.tree_it) 
        {
            tree_it.tree = &tree;
        };

        int num_of_files;
        map<int, pair<int, string> > names;
        vector<pair<int, int> > edges;

        Tree< pair<int, string> > tree;
        TreeIterator< pair<int, string> > tree_it;

        string input_format;
        string output_format;

        static Unix_tree* load_tree(istream& input_info);
        void load_names(istream& input_info);
        void load_tree_nodes(vector<int>& levels);
        Unix_tree* convert(string format);

        virtual void load(istream& input_info) = 0;
        virtual void print_function(const Tree<pair<int, string> >* node, const vector<bool>& visited ) = 0;
        void print_tree();
    };


    class Unix_tree_type1 : public Unix_tree
    {
    public:

        void load(istream& input_info);
        void print_function(const Tree<pair<int, string> >* node, const vector<bool>& visited);
    };

4 个答案:

答案 0 :(得分:1)

您可以投射指针,所以:

Unix_tree *p = ...;
Unix_tree_type1 *q = (Unix_tree_type1*)p;

但我不认为你想这样做。方法调用会自动执行您想要的操作,因此:

Unix_tree *p = ...; // points to an instance of Unix_tree_type1
p->load(...);       // calls Unix_tree_type1::load, not Unix_tree::load

答案 1 :(得分:1)

你可以施放,但你不应该。您应该只调用基类指向的对象的成员函数,并调用您的实现。这就是虚拟成员函数的重点。

答案 2 :(得分:1)

没有办法将基类强制转换为派生类,因为它没有意义。在没有涉及太多OO细节的情况下,从基类继承的目的不仅仅是“打印基类中包含的数据” - 而是提供更具体的功能实现。所以想象一下“Fruit”类,其方法是“GetJuice()”。继承自“Fruit”的类“Apple”可能会继承方法“GetJuice()”。但是,除了该方法之外,它还可以定义其他方法或属性,例如“FindAppleWorm()”,这些方法或属性将特定于其类型。因此,当你有一个Apple类时,可以将它强制转换为类型fruit,并且调用Fruit类的“GetJuice()”方法仍然是有意义的。但是,如果将一个Fruit类转换为Apple类,您可以调用“FindAppleWorm()”方法,但它不会出现。

面向对象语言中的继承概念与多态的概念相辅相成。我建议wikipedia article进行一次很好的介绍。

答案 3 :(得分:0)

为什么你不能?当然,你可以 - 它是有效的上传,可以由dynamic_cast完成。但你应该投射指针或引用,而不是类型本身。

Unix_tree_type1* ptree1 = ...; // Some pointer initialization
Unix_tree* ptree2 = dynamic_cast<Unix_tree*>(ptree1);// Safe
Unix_tree* ptree3 = static_cast<Unix_tree*>(ptree1); // Also safe