投射到一个孩子 [英] Cast to a Child

查看:203
本文介绍了投射到一个孩子的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我实际想要做的是将 moneypunct 转换到中的 punct_facet http://stackoverflow.com/q/31291004/2642059\">此问题,无需编写复制构造函数,如此回答



但是,为了撰写最小,完整,可验证的示例假设我有这两个类:

  class Parent {
public:
Parent(Complex& args);
父运算符=(const Parent&)= delete;
Parent(const Parent&)= delete;
Parent()= default;

virtual void func();
private:
复杂成员;
};

class Child:public Parent {
public:
virtual void func();
};

我可以构建 Child 使用默认构造函数,但不会设置复杂成员。所以说我得到 Parent foo 这是使用自定义构造函数构造的,我想使用 foo 对象与 Child func 方法。我怎么做?直到 dynamic_cast< Child *>(& foo) segfaults,因此可能没有办法: http://ideone.com/JcAaxd

  auto bar = dynamic_cast<儿童*>(& foo); 

我必须创建一个 Child 构造函数需要一个 Parent 并在内部复制吗?

编辑:



为了深入了解我的实际问题,示例中的 Parent moneypunct

class punct_facet 是我的从示例中的 Child ,它继承 moneypunct ,如果我试图保持实现独立我甚至不能内部使用 moneypunct 的成员变量。



这意味着我必须镜像所有 moneypunct punct_facet 中的成员变量,并在 punct_facet 构造上复制它们。这导致一个对象,它的需要是脂肪的两倍,并要求我重新实施所有 moneypunct 功能。



显然这是不可取的,但我可以找到的唯一方法是采取一个以前构造的 moneypunct 并将其视为 punct_facet

解决方案

这不会像你想的那样工作, code> func virtual。这意味着即使您要将指针转换为 Child 的指针 Parent 该对象的c> func()仍然是 Parent :: func()



现在,你理论上可以做这样的事情:

  #include< iostream> 

class Parent
{
public:
virtual void foo(){std :: cout< parent<< std :: endl; }
};

class Child:public Parent
{
public:
virtual void foo(){std :: cout< child<< std :: endl; }
};

int main()
{
子child;
child.foo(); //child
child.Parent :: foo(); //parent
父父;
parent.foo(); //parent
((Child *)(& parent)) - > foo // stillparent
((Child *)(& parent)) - > Child :: foo(); //child
return 0;
}

虽然我可能会收到一些downvote张贴这个破碎的代码,有必要显示在这种情况下发生了什么。你需要转换两个,指向对象的指针,然后指定你打算调用哪个函数。



根据你在做什么,它可能更好使用朋友类完成:

  #include< iostream> 

class ParentHelper;
class ChildHelper;
class Parent
{
friend class ParentHelper;
friend class ChildHelper;
private:
int a = 5;
};

class ParentHelper
{
public:
virtual void func(Parent * p)
{
std :: cout< 父助手,但我看到一个< p - > a<< std :: endl;
}
};

class ChildHelper:public ParentHelper
{
public:
virtual void func(Parent * p)
{
std :: cout< ;& 儿童帮手,但我看到了一个< p - > a< std :: endl;
}
};

void foo(Parent * p,ParentHelper * h)
{
h-> func(p);
}

int main()
{
父p;
ParentHelper ph;
ChildHelper ch;

ph.func(& p);
ch.func(& p);

foo(& p,& ph);
foo(& p,& ch);

return 0;
}

注意几件事:


  1. 友谊不会继承,所以你必须将所有的孩子列出给你想要使用的ParentHelper。

  2. 但是,要访问您的Parent类的所有数据成员,它不会导致一些奇怪的行为。

  3. 这可能仍然不是你要找的,但从你的问题,我认为


What I'm actually trying to do is cast a constructed moneypunct to the punct_facet in this question without writing a copy constructor as in this answer.

But in the interests of writing a Minimal, Complete, Verifiable Example let's say that I have these two classes:

class Parent{
public:
    Parent(Complex& args);
    Parent operator=(const Parent&) = delete;
    Parent(const Parent&) = delete;
    Parent() = default;

    virtual void func();
private:
    Complex members;
};

class Child : public Parent{
public:
    virtual void func();
};

I can construct a Parent or Child with the default constructor but that won't setup Complex members. So say that I am given Parent foo which was constructed using the custom constructor and I want to use the foo object just with Child's func method. How do I do that? The straight up dynamic_cast<Child*>(&foo) segfaults, so there may not be a way: http://ideone.com/JcAaxd

auto bar = dynamic_cast<Child*>(&foo);

Do I have to make a Child constructor that takes a Parent and internally copies it? Or is there some way to cast bar into existence?

EDIT:

To give insight into my actual problem, the Parent from the example is moneypunct, which is implemented in the standard so I cannot modify it.

class punct_facet is mine and the Child from the example, it inherits moneypunct and if I'm trying to stay implementation independent I cannot even internally use moneypunct's member variables.

Which means that I must data mirror all of moneypunct member variables in punct_facet and copy construct them on punct_facet construction. This results in an object that's twice as fat as it needs to be and requires me to reimplment all moneypunct functionality.

Clearly that's undesirable, but the only way I can find around it is to take a previously constructed moneypunct and treat it as a punct_facet as requested by this question.

解决方案

It wouldn't work as you think, since you have made the function func virtual. This means that even if you were to convert the pointer to Parent to a pointer to Child, the func() of that object would still be Parent::func().

Now, you could theoretically do something like this:

#include <iostream>

class Parent
{
public:
        virtual void foo() { std::cout << "parent" << std::endl; }
};

class Child : public Parent
{
public:
        virtual void foo() { std::cout << "child" << std::endl; }
};

int main()
{
        Child child;
        child.foo(); // "child"
        child.Parent::foo(); // "parent"
        Parent parent;
        parent.foo(); // "parent"
        ((Child*)(&parent))->foo(); // still "parent"
        ((Child*)(&parent))->Child::foo(); // "child"
        return 0;
}

And while i may receive some downvotes for posting this broken code, i think that it is necessary to show what is happening in this case. You would need to convert both, the pointer to the object, and then specify exactly which function you are intending to call.

Depending upon what you are doing, it may better be accomplished by using friend classes:

#include <iostream>

class ParentHelper;
class ChildHelper;
class Parent
{
    friend class ParentHelper;
    friend class ChildHelper;
private:
    int a=5;
};

class ParentHelper
{
public:
    virtual void func(Parent *p)
    {
        std::cout << "parent helper, but i see a " << p->a << std::endl;
    }
};

class ChildHelper : public ParentHelper
{
public:
    virtual void func(Parent *p)
    {
        std::cout << "child helper, but i see a also " << p->a << std::endl;
    }
};

void foo(Parent* p, ParentHelper *h)
{
    h->func(p);
}

int main()
{
    Parent p;
    ParentHelper ph;
    ChildHelper ch;

    ph.func(&p);
    ch.func(&p);

    foo(&p, &ph);
    foo(&p, &ch);

    return 0;
}

Note several things:

  1. Friendships are not inherited, so you must then list all children to ParentHelper that you intend to use.
  2. It does, however, give you a way to access all the data members of your Parent class as is, it won't cause some weird behaviour.
  3. This may still not be what you are looking for, but from your question i think that it may help.

这篇关于投射到一个孩子的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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