为什么在私有继承中,派生* 到基* 之间的转换会失败?
这是我的代码 -
#include<iostream>
using namespace std;
class base
{
public:
void sid()
{
}
};
class derived : private base
{
public:
void sid()
{
}
};
int main()
{
base * ptr;
ptr = new derived; // error: 'base' is an inaccessible base of 'derived'
ptr->sid();
return 0;
}
这会产生编译时错误。
error: 'base' is an inaccessible base of 'derived'
既然编译器会尝试调用基类 sid()
为什么我会收到此错误?有人可以解释一下吗?
Here is my code -
#include<iostream>
using namespace std;
class base
{
public:
void sid()
{
}
};
class derived : private base
{
public:
void sid()
{
}
};
int main()
{
base * ptr;
ptr = new derived; // error: 'base' is an inaccessible base of 'derived'
ptr->sid();
return 0;
}
This gives a compile time error.
error: 'base' is an inaccessible base of 'derived'
Since the compiler will try and call the base class sid()
why do I get this error? Can someone please explain this.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(7)
我怀疑问题在于您无法将派生指针转换为基指针,因为继承是私有的。
I suspect the problem is that you can't convert a derived pointer to a base pointer, as the inheritance is private.
$11.2/4 州-
这里 'B' 是 'Base','N' 是 'Derived','R' 是 main。
考虑第二个项目符号 - 'R 出现在 N 类的成员或朋友中,.. .'。本子句不适用,因为 'R'(主)既不是 'N'(派生)的成员也不是友元
考虑第三个项目符号 -“R 出现在 P 类的成员或友元中” ....'。出于与上述相同的原因,该条款也不适用
考虑第四个项目符号-再次此条款不适用
因此我们可以得出结论“Base”不是可访问的“派生”类别
$11.2/5 表示 -
由于在
main
中访问时Base
不是Derived
的可访问类,因此从 Derived 类进行标准转换到基类的格式不正确。因此出现了错误。编辑 2:
研究一些流行编译器的错误消息,这应该可以帮助您更好地理解。请注意“无法访问”一词如何在所有错误消息中如此频繁且一致地弹出
。参考资料来自标准草案 N3000。我还没有下载最新的草稿:)
$11.2/4 states-
Here 'B' is 'Base', 'N' is 'Derived' and 'R' is main.
Consider the 2nd bullet- 'R occurs in a member or friend of a class N,...'. This clause does not apply as 'R'(main) is neither a member nor friend of 'N'(Derived)
Consider the 3rd bullet- 'R occurs in a member or friend of a class P....'. This claus also does not apply for the same reasons as above
Consider the 4th bullet- Once again this clause does not apply
Thus we can conclude that 'Base' is not an accessible class of 'Derived'.
$11.2/5 states -
Since
Base
is not an accessible class ofDerived
when accessed inmain
, the Standard conversion from Derived class to Base class is ill-formed. Hence the error.EDIT 2:
Study the error messages of some popular compilers and that should help you get a better understanding. Note how the word 'inaccessible' pops up so frequently and consistently across all the error messages
The references are from the draft standard N3000. I am yet to download the latest draft :)
Chusbad 提供了涉及该标准的深入解释,我将尽力提供一个易于理解的解释。
在 C++ 中,有 3 个访问级别说明符:
public
、protected
和private
。这些旨在确定谁可以访问方法、属性或基类。它是面向对象语言中的典型。在这里,您选择了
私有
继承。从概念上讲,这意味着您试图向外部人员隐藏Derived
继承自Base
的事实,这通常意味着这是一个实现细节。因此,“外部”并不知道这种关系。这是由编译器通过此
inaccessible
消息强制执行的。从设计的角度来看,通常不需要
私有
继承。要么应用里氏替换原则并使用公共继承,要么它是实现细节并使用组合。Chusbad provided an in-depth explanation involving the standard, I'll try to provide an accessible explanation.
In C++, there are 3 access level specifiers:
public
,protected
andprivate
. Those are meant to determine WHO can access methods, attributes or base classes. It is typical amongst Object Oriented languages.Here, you elected
private
inheritance. Conceptually this means that you seek to HIDE the fact thatDerived
inherits fromBase
to outsiders, which generally means this is an implementation details.As a consequence, the "exterior" is unaware of this relationship. This is enforced by the compiler with this
inaccessible
message.From a design point of view,
private
inheritance is not generally required. Either the Liskov Substitution Principle applies and you usepublic
inheritance, either it's an implementation detail and you use composition.您知道
派生类
继承自类基
,但main()
函数不知道这一点。main()
函数不知道的原因是您使派生类
从基类
私有继承。因此,当您尝试将
new衍生
分配给ptr
时,指针类型不兼容。You know that
class derived
inherits fromclass base
, but themain()
function doesn't know it. The reason themain()
function doesn't know it is that you madeclass derived
inherit PRIVATELY fromclass base
.Therefore when you try to assign
new derived
toptr
, the pointer types are not compatible.试试这个:
Try this:
这给出了错误 C2243:“类型转换”:从“派生 *”到“基 *”的转换存在,但无法访问
该派生类已被私有继承。因此,当派生类创建时,不会创建基类对象。要创建派生对象,首先调用创建未发生的基类对象。
解决方案是公开派生该类。是否在成员函数中使用 virtual 关键字并不重要。
this gives error C2243: 'type cast' : conversion from 'derived *' to 'base *' exists, but is inaccessible
This derived class has been inherited privately .so base class object is not gets created when derieved get creation happens. to create the derive object first calls goes to create the base class object that not happening.
soltuion is to derive the class publicly. it doesnit matter whether your using virtual keyword with member functions or not.
您需要将基类中的 sid() 函数声明为虚拟函数。虚函数可以用派生类代替。否则,您可能会收到编译器错误。
You need to declare your sid() function in the base class as virtual. A virtual function can be replaced by a derived class. Otherwise, you would likely get a compiler error.