c-演员

我实际上想做的是在this question中将构造好的moneypunct转换为punct_facet,而不像this answer那样编写副本构造函数.

但是出于编写Minimal, Complete, Verifiable Example的利益,我们可以说我有以下两个类:

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();
};

我可以使用默认构造函数构造一个Parent或Child,但是不会设置Complex成员.可以这么说,我给了Parent foo,它是使用自定义构造函数构造的,并且我想仅通过Child的func方法使用foo对象.我怎么做?直截了当的dynamic_cast< Child *>(& foo)段错误,因此可能没有办法:http://ideone.com/JcAaxd

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

我是否必须让一个Child构造函数接受一个Parent并在内部复制它?还是有某种方法可以阻止存在?

编辑:

为了深入了解我的实际问题,示例中的父项是moneypunct,它是在标准中实现的,因此我无法对其进行修改.

punct_facet类是我的,并且是该示例中的Child,它继承了moneypunct,如果我尝试保持实现独立性,我什至不能在内部使用moneypunct的成员变量.

这意味着我必须对punct_facet中的所有moneypunct成员变量进行数据镜像,并在punct_facet构造中进行复制构造.这导致对象的脂肪是需要的两倍,并且需要我重新实现所有的moneypunct功能.

显然这是不可取的,但是我能找到的唯一方法是采用先前构造的moneypunct并将其视为此问题要求的punct_facet.

解决方法:

因为您已经将函数func虚拟化了,所以它无法按照您的想法工作.这意味着即使您将指向Parent的指针转换为指向Child的指针,该对象的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;
        child.foo(); // "child"
        child.Parent::foo(); // "parent"
        Parent parent;
        parent.foo(); // "parent"
        ((Child*)(&parent))->foo(); // still "parent"
        ((Child*)(&parent))->Child::foo(); // "child"
        return 0;
}

虽然我可能会因发布此破损代码而收到一些不满,但我认为有必要展示这种情况下的情况.您将需要将这两个指针都转换为对象,然后准确指定要调用的函数.

根据您在做什么,最好通过使用好友类来实现:

#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;
}

注意几件事:

>友谊不会被继承,因此您必须随后将要使用的所有子项列出到ParentHelper中.
>但是,它的确为您提供了一种直接访问Parent类的所有数据成员的方法,它不会引起某些奇怪的行为.
>这可能仍然不是您想要的东西,但是从您的问题来看,我认为这可能会有所帮助.

上一篇:在C抽象类中将回调(用于C库)实现为纯虚拟的


下一篇:c运算符重载的多态性