English 中文(简体)
C++ 公共和私人遗产
原标题:Public and private inheritance in C++

正如我们从公共遗产文献中知道的那样,儿童阶级(子级)的目标也可以被视为基础阶层(超级阶级)的目标。 当遗产被保护或私人继承时,为何不能将子类的物体视为超级阶级的物体?

最佳回答

因为你可以发现:

class Base
{
    public: virtual ~Base() {}
};

class PublicDerived: public Base
{    };

class PrivateDerived: private Base
{    };

int main()
{
    PublicDerived   publicD;
    PrivateDerived  privateD;

    Base&           base1 = publicD;
    Base&           base2 = privateD; // ERROR
} 

So you can not use a PrivateDerived object where a Base object could be used.
So it will never act like a Base class object.

问题回答

总的来说,您将在文献中(以及此处的其他答复中)找到<编码>受保护的/ 私人。 继承意味着不能将该类别用作<条码>。 事实(其中还有一些答案)是,只有遗产的可见度受到这项行动的影响。 。 页: 1

任何<条码>友好关系或班级都能够利用这一关系:

struct base {
   virtual void foo() { std::cout << "base" << std::endl; }
};
void take_base( base& b ) {}
class derived : base // private {
   friend base& to_base( derived& );
   virtual void foo() { std::cout << "derived" << std::endl; }
public:
   base & as_base() { return *this; }
   void call_function() { take_base(*this); } // ok: inside derived, it knows that it is
                                              // in fact a base
};
base& to_base( derived& d ) {
   return d;
}
int main() {
   derived d;
   //d.foo();      // error
   //take_base(d); // error
   take_base( d.as_base() ); // ok, the conversion is performed internally where
                             // access is granted: print "derived"
   take_base( to_base(d) );  // ok, the conversion is performed in a friend function
                             // that has access: print "derived"
}

现在,虽然在技术上是这样,但在你使用<条码>私人<>/条码>继承时,你试图模仿“条码”而不是“条码/代码”的关系,而是“条码”。 这是重要部分:在阅读守则时,如果见 / private。 您的继承不应在is-a上考虑,而应在上执行。

简言之,由于私人继承是执行<>>>,而不是interface的继承。 缩略语 <代码>Base。 <代码>Base的公众和保护成员可见于<代码>Derived,但他们成为 private,因此外部世界无法进入。 因此,可将私人继承视为一种特殊形式的composition,事实上在实践中很少需要这种形式。 (受保护的继承权实际上从来不去——事实上甚至连Bjarne Stroustrup也不知道什么保护的继承权。)

在考虑该机制如何运作时,“水”是简单的:因为受保护和私人继承意在以这种方式发挥作用。

这可能不足以解决问题的意图。 如果你不把由此产生的物体作为基类的事例,那么你可能会问“为什么<> >有私人和受保护的继承?”

诚然,非公共继承意在促进两个阶层之间的“从”关系(当公共继承促进“主体-a”关系时)。 换言之,你打算重复部分或全部基级功能,向自己的消费者提供服务。

这一设想几乎总是通过合并而不是继承(即拥有“基地”类别成员的目标)得到更好的执行,我可以说,非公共继承是更好的选择。

查阅,以便进行更长的写作,从而扩大上述内容。

<>Update:作为以下评论者,有一些(被认为很少)非公共继承为建筑功能提供机制,否则不可能。 读到这些语言,因为探索一种语言的边缘,可以很有启发性。 但是,试图做的只是你所能做的。

<条码>公开 继承为亲子关系的目的。 也就是说:

class A {};
class B : public A {};

Class B is a version of class A.

<条码>私人 继承为“内部关系”的目的。 您可以采用集装箱模式,用私人遗产撰写几乎所有的类别:

class A {};
class B : private A {};

can be rewritten (and more often than not, should be rewritten for clarity):

class A {};
class B
{
private:
    A a;
};

你们可以想到公共/受保护/私人遗产,如任何阶层成员均可获得的遗产:这是你们想要显示多少东西的问题。

私人(或以稍有不同的方式加以保护)继承是一种未见于外部世界的关系。 因此,你可以把衍生物视为其私人基础,因为你没有“看到”这种关系甚至存在。

Why the object of the sub-class can’t be considered as an object of super-class, when the inheritance is protected or private?

www.un.org/Depts/DGACM/index_spanish.htm 这当然可被视为超级阶级的物体。 然而,这种考虑受到限制(由公共/保护/私人继承人进行),但仅限于 /strong>(私人继承)或 次类别(受保护的继承)。

不允许所有外部物体视同这种类别,与它们不允许接触受保护或私人方法或变量。 如果适当表述,这种类比就相当合适。

因此,阶级本身、其子阶级(和朋友)可以将此视为一种亲子关系,但外部世界不允许这样做。

下面的法典在行动中表明了这一点:

class Base {
    public: virtual ~Base() {}
};

class PublicDerived: public Base
{ };

class ProtectedDerived: protected Base {
    void test() {
        Base* base2 = this; // OK
    }
};

class ProtectedSubClass: public ProtectedDerived {
    void test() {
        Base* base2 = this; // OK
    }
};

class PrivateDerived: private Base {
    void test() {
        Base* base2 = this; // OK
    }
};

class PrivateSubClass: public PrivateDerived {
    void test() {
        Base* base2 = this; // Error (line 28)
    }
};

int main()
{
    PublicDerived   publicD;
    ProtectedDerived protectedD;
    PrivateDerived  privateD;

    Base* base1 = &publicD;
    Base* base2 = &protectedD; // Error (line 39)
    Base* base3 = &privateD; // Error (line 40)
} 

请注意,这并不涉及xxxSubClass-classes如何从其超级类别中得出。 www.un.org/Depts/DGACM/index_french.htm

编辑们适当抱怨:

inherit.cpp(28) : error C2247:  Base  not accessible because  PrivateDerived  uses  private  to inherit from  Base 
        inherit.cpp(1) : see declaration of  Base 
        inherit.cpp(20) : see declaration of  PrivateDerived 
        inherit.cpp(1) : see declaration of  Base 
inherit.cpp(29) : error C2243:  type cast  : conversion from  PrivateSubClass *const   to  Base *  exists, but is inaccessible
inherit.cpp(39) : error C2243:  type cast  : conversion from  ProtectedDerived *  to  Base *  exists, but is inaccessible
inherit.cpp(40) : error C2243:  type cast  : conversion from  PrivateDerived *  to  Base *  exists, but is inaccessible




相关问题
Undefined reference

I m getting this linker error. I know a way around it, but it s bugging me because another part of the project s linking fine and it s designed almost identically. First, I have namespace LCD. Then I ...

C++ Equivalent of Tidy

Is there an equivalent to tidy for HTML code for C++? I have searched on the internet, but I find nothing but C++ wrappers for tidy, etc... I think the keyword tidy is what has me hung up. I am ...

Template Classes in C++ ... a required skill set?

I m new to C++ and am wondering how much time I should invest in learning how to implement template classes. Are they widely used in industry, or is this something I should move through quickly?

Print possible strings created from a Number

Given a 10 digit Telephone Number, we have to print all possible strings created from that. The mapping of the numbers is the one as exactly on a phone s keypad. i.e. for 1,0-> No Letter for 2->...

typedef ing STL wstring

Why is it when i do the following i get errors when relating to with wchar_t? namespace Foo { typedef std::wstring String; } Now i declare all my strings as Foo::String through out the program, ...

C# Marshal / Pinvoke CBitmap?

I cannot figure out how to marshal a C++ CBitmap to a C# Bitmap or Image class. My import looks like this: [DllImport(@"test.dll", CharSet = CharSet.Unicode)] public static extern IntPtr ...

Window iconification status via Xlib

Is it possible to check with the means of pure X11/Xlib only whether the given window is iconified/minimized, and, if it is, how?