C++ 摆脱错误C2243

C++ 摆脱错误C2243,c++,inheritance,casting,implicit-conversion,C++,Inheritance,Casting,Implicit Conversion,有没有可能摆脱它 我的应用程序中有这个错误,最后我通过显式转换成功编译了它: D d; B *p = (B*)&d; 我不明白为什么从B继承D类使隐式转换无法访问 我试图通过在类D中创建运算符B()来避免显式转换,以便可以访问转换: class B {}; class D : protected B { public: operator B() {return *this;} }; 但是没有办法 避免显式转换的任何其他解决方案?因为受保护的和私有的继承不是is-a关系,它们只是

有没有可能摆脱它

我的应用程序中有这个错误,最后我通过显式转换成功编译了它:

D d;
B *p = (B*)&d;
我不明白为什么从B继承D类使隐式转换无法访问

我试图通过在类D中创建运算符B()来避免显式转换,以便可以访问转换:

class B {};
class D : protected B 
{
 public:
 operator B() {return *this;}
};
但是没有办法


避免显式转换的任何其他解决方案?

因为
受保护的
私有的
继承不是
is-a
关系,它们只是合成的语法糖。您的类可以像这样重写,但是您失去了让编译器为您定义
b
以及直接使用b成员而不是显式引用它的便利:

class D
{
  protected:
  B b;
};

关于你问题的第二点:

operator B() {return *this;}
这一行与
B
D
有关。D*和B*与B和D完全不同,尽管它们是指向它们的指针!要转换指针,可以重新解释指针:

B *p = reinterpret_cast<B*>(&d); // TOTALLY WRONG, although it compiles :)
B*p=reinterpret_cast(&d);//完全错误,尽管它编译:)

不要做上面的事!我认为您可能会向我们提供更多有关您试图实现的目标的信息。

如果您希望允许转换,您应该使用公共继承

使用受保护继承或私有继承,可以声明派生类型从基类继承的事实是一个从外部看不到的细节:这就是为什么会出现该错误


您应该只将非公共继承视为一种组合形式,并增加了重写方法的可能性

因为在D和Ds子对象中,没有人知道它们是父子对象,所以您需要明确地这样做

这就是受保护遗产的含义,只有你的家人(孩子)知道你继承了遗产。您可以使用它,例如在children方法中,隐式转换是合法的


如果你想从你的孩子身上进行隐式转换,你需要让每个人都知道它。

你有没有试着让操作符B()在类D中公开?在您显示的代码中,它将被标记为受保护且仍然不可访问。但如果可能的话,我一般会避免使用转换运算符

不过,继承受保护的B意味着您打算阻止执行B*p=&d。想象一下,如果B实际上是D顶部的一个受保护的成员变量。就像在这种情况下不能访问D.B一样,除非将其丢弃,否则不能作为B*访问D


因此,要么公开继承B,要么使用您的类型转换。我倾向于公开继承B,因为继承受保护的B基本上是说“不要将我用作B”,你无论如何都要这样做。

这里的问题是,你试图对受保护的属性所提供的信息隐藏进行一次结束。如果要以B的形式访问D的实例,为什么要将其作为受保护而不是公共继承?。在使用受保护继承时,您所说的是,您只希望D及其子体的实例知道B组件。你需要再次审视你想要实现的目标


旧的C样式的CUP没有新的C++版本的精妙之处,所以它给你编译的代码,但是问题实际上在继承中。

< P>因为没有人知道它是父子关系,你只能在D的派生类中执行这个动作。这是一个例子(VisualStudio 2013中的测试):


只允许访问基类的const接口怎么样?所以私下继承并允许向const base&?询问,因为它无法在MSVC上工作…只是回答我自己,您需要通过聚合而不是继承来处理该类,否则MSVC会感到困惑,并尝试通过私有继承(隐藏cast运算符)来解决转换问题
B *p = reinterpret_cast<B*>(&d); // TOTALLY WRONG, although it compiles :)
class BASE{};

class BASE1 :protected BASE{};

class BASE2 :protected BASE1
{
public:
    void func(BASE &a, BASE1 &b){a = b;}
};

void main()
{
    BASE a;
    BASE1 b;
    BASE2 c;

    c.func(a, b);;
    system("pause");
 }