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,casting,polymorphism,inheritance,virtual-functions 来源: https://codeday.me/bug/20191013/1907534.html