c++中公共继承、私有继承和受保护继承之间的区别是什么?

我在SO上找到的所有问题都是针对具体案例的。


当前回答

1)公共继承:

a.基类的私有成员在派生类中不可访问。

b.基类的受保护成员在派生类中仍然受保护。

c.基类的公共成员在派生类中保持为公共。

因此,其他类可以通过派生类对象使用基类的公共成员。

2)受保护遗产:

a.基类的私有成员在派生类中不可访问。

b.基类的受保护成员在派生类中仍然受保护。

c.基类的公共成员也成为派生类的受保护成员。

因此,其他类不能通过派生类对象使用基类的公共成员;但它们可用于派生的子类。

3)私人继承:

a.基类的私有成员在派生类中不可访问。

b.基类的Protected & public成员变成派生类的private成员。

因此,基类的成员不能被其他类通过派生类对象访问,因为它们在派生类中是私有的。甚至是Derived的子类 类不能访问它们。

其他回答

简介:

Private:除了类内部,没有人可以看到它 Protected: Private +派生类可以看到它 公众:全世界都能看到

在继承时,你可以(在某些语言中)在某个方向上改变数据成员的保护类型,例如从protected变为public。

任何继承自您的类的类都可以访问受保护的数据成员。但是,私有数据成员不能。假设我们有以下内容:

class MyClass {
    private:
        int myPrivateMember;    // lol
    protected:
        int myProtectedMember;
};

从扩展到这个类,引用这个。myPrivateMember不能工作。然而,这。myProtectedMember意志。这个值仍然是封装的,所以如果我们有一个myObj类的实例化,那么myObj。myProtectedMember不能工作,所以它的功能类似于私有数据成员。

1)公共继承:

a.基类的私有成员在派生类中不可访问。

b.基类的受保护成员在派生类中仍然受保护。

c.基类的公共成员在派生类中保持为公共。

因此,其他类可以通过派生类对象使用基类的公共成员。

2)受保护遗产:

a.基类的私有成员在派生类中不可访问。

b.基类的受保护成员在派生类中仍然受保护。

c.基类的公共成员也成为派生类的受保护成员。

因此,其他类不能通过派生类对象使用基类的公共成员;但它们可用于派生的子类。

3)私人继承:

a.基类的私有成员在派生类中不可访问。

b.基类的Protected & public成员变成派生类的private成员。

因此,基类的成员不能被其他类通过派生类对象访问,因为它们在派生类中是私有的。甚至是Derived的子类 类不能访问它们。

这三个关键字还在完全不同的上下文中用于指定可见性继承模型。

这个表收集了组件声明和继承模型的所有可能组合,表示在子类完全定义后对组件的最终访问。

上表的解释如下(看第一行):

如果一个组件被声明为公共的,并且它的类被继承为公共的,那么得到的访问是公共的。

一个例子:

 class Super {
    public:      int p;
    private:     int q;
    protected:   int r;
 };

 class Sub : private Super {};

 class Subsub : public Sub {};

Subsub类中变量p, q, r的访问结果为none。

另一个例子:

class Super {
    private:     int x;
    protected:   int y;
    public:      int z;
 };
class Sub : protected Super {};

类Sub中对变量y, z的访问受到保护,对变量x的访问为none。

一个更详细的例子:

class Super {
private:
    int storage;
public:
    void put(int val) { storage = val;  }
    int  get(void)    { return storage; }
};
int main(void) {
    Super object;

    object.put(100);
    object.put(object.get());
    cout << object.get() << endl;
    return 0;
}

现在让我们定义一个子类:

class Sub : Super { };

int main(void) {
    Sub object;

    object.put(100);
    object.put(object.get());
    cout << object.get() << endl;
    return 0;
}

定义了一个名为Sub的类,它是一个名为Super的类的子类,或者这个子类是从Super类派生的。 子类既不引入新变量也不引入新函数。这是否意味着子类的任何对象都继承了父类之后的所有特征,实际上是父类对象的副本?

不。它不是。

如果我们编译下面的代码,我们只会得到编译错误,表示put和get方法不可访问。为什么?

当省略可见性说明符时,编译器假定我们将应用所谓的私有继承。这意味着所有的公共超类组件都变成了私有访问,私有超类组件将根本无法访问。因此,这意味着不允许在子类中使用后者。

我们必须通知编译器我们想要保留以前使用的访问策略。

class Sub : public Super { };

不要被误导:这并不意味着私人组件的超 类(如存储变量)将转换为公共类 有点神奇。私有组件将保持私有、公开 将继续公开。

子类的对象可以做“几乎”与从超类创建的它们的哥哥姐姐相同的事情。“几乎”是因为作为子类的事实也意味着该类失去了对超类的私有组件的访问权。子类的成员函数不能直接操作存储变量。

这是一个非常严重的限制。有什么解决办法吗?

Yes.

第三个访问级别称为受保护。关键字protected意味着标记了它的组件在被任何子类使用时表现得像一个公共组件,而对其他组件看起来像一个私有组件。——这只适用于公共继承的类(比如我们例子中的Super类)——

class Super {
protected:
    int storage;
public:
    void put(int val) { storage = val;  }
    int  get(void)    { return storage; }
};

class Sub : public Super {
public:
    void print(void) {cout << "storage = " << storage;}
};

int main(void) {
    Sub object;

    object.put(100);
    object.put(object.get() + 1);
    object.print();
    return 0;
}

正如你在示例代码中看到的,我们给子类添加了一个新功能,它做了一件重要的事情:它从超类访问存储变量。

如果变量被声明为私有,这是不可能的。 在main函数的作用域中,变量仍然是隐藏的,所以如果你这样写:

object.storage = 0;

编译器会告诉你这是一个错误:'int Super::storage'是受保护的。

最后,最后一个程序将产生以下输出:

storage = 101
Member in base class : Private   Protected   Public   

继承类型:对象继承为:

Private            :   Inaccessible   Private     Private   
Protected          :   Inaccessible   Protected   Protected  
Public             :   Inaccessible   Protected   Public