如何在C ++的私人基类中实施铸造?我不想使用诸如添加朋友等的黑客攻击。定义公共铸造操作员不起作用。

编辑 :

例如,我有:

class A {
//base class
}

class AX : private A {
//a child
}

class AY : private A {
//another specialized child
}

class B {
//base class
void do (A a) {//do
    }
}

class BX : private B {
//a child
void do (AX a) {
     B::do( static_cast <A> (a) );
    }
}

class BY : private B {
//another specialized child
void do (AY a) {
    B::do( static_cast <A> (a) );
    }
}

Edit2

我为什么要这样做?

假设我必须定义一些非常重量的属性,并且可以是几种类似类型的类型(例如Velocityx Velocityy等)。然后,我希望能够拥有可以拥有任何这些属性的类。如果我想处理这些属性,很明显,我宁愿将它们投入其基本类型,而不是为每个变体添加实现。我不使用公共继承,因为比让私人接口隐含可见的地方要明确地施放在需要的地方。不是一个真正的问题,但我想有解决方案:)

有帮助吗?

解决方案

如果定义公共铸造操作员不起作用,则可以尝试使用常规功能:

class D: private B {
    public:
        B& asB() { return static_cast<B&>(*this); }
};
...
D d;
d.asB().methodInB();
...

无论如何,重点是什么?如果 D 私下来 B, ,那么您不应该使用 D 作为一个 B 从外部。

其他提示

您只能使用C风格的演员。无需任何“黑客”或“实施”。将其包裹在明确的功能中,服务于“ C风格的演员阵容不好”的人

template<typename Targ, typename Src>
typename boost::enable_if<boost::is_base_of<Targ, Src>, Targ>::type &
private_cast(Src &src) { return (Targ&)src; }

要确保演员的安全,您需要确保 Targ 实际上是私人或公共基础。这是由 boost::is_base_of.


当然,您应该在返回基本指针的各个派生类中更喜欢成员函数,而不是这样做。.


定义公共铸造操作员行不通。

那对我来说没有意义...为什么要使基类私密呢?只是公开。您的转换函数不起作用的原因是因为标准要求隐式转换永远不会考虑转换函数到基类,类本身或 void.

我有一个用例;我正在继承一个始终添加函数的大型且挥发性的基类,几乎永远不会是基类函数在我的子类中正确工作,因此我私下继承。

我认为仅仅是返回基类的函数是最简单的。下面我列出了一个完全校正的程序;请在提交问题之前尝试编译代码,因为使用诸如“ do”作为函数名称之类的标识符可能会使每个编译器不快乐。.:-( :-(

class A {
  //base class                                                                                                                                                          
};

class AX : private A {
  //a child                                                                                                                                                             
 public:
  A *ToA() { return this; }
};

class AY : private A {
  //another specialized child                                                                                                                                           
 public:
  A *ToA() { return this; }
};

class B {
  //base class                                                                                                                                                          
 protected:
  void do_it (A a) {};
};

class BX : private B {
  //a child                                                                                                                                                             
  void do_it (AX a) {
    B::do_it( *a.ToA() );
  }
};

class BY : private B {
  //another specialized child                                                                                                                                           
  void do_it (AX a) {
    B::do_it( *a.ToA() );
  }
};

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top