基本上,据我知道,当你创建一个基类与公共,保护,并在每个受保护的公共部分私人部分和变量/功能将得到继承到子类的适当部分(由类的子类中定义:私人基地,这将基地的所有公共和保护成员,并把它们纳入公共,私有改变公共字把他们所有的公共和其更改为保护把他们全部纳入保护)。
所以,当你创建一个子类,你永远不会收到从以前的类(在这种情况下,基类)的私有部分东西,如果这是真的,那么子类的对象不应该有它的自己的版本从基类正确私有变量或函数?
让我们跑过来一个例子:
#include <iostream>
class myClass // Creates a class titled myClass with a public section and a private section.
{
public:
void setMyVariable();
int getMyVariable();
private:
int myVariable; // This private member variable should never be inherited.
};
class yourClass : public myClass {}; // Creates a sub-class of myClass that inherits all the public/protected members into the
// public section of yourClass. This should only inherit setMyVariable()
// and getMyVariable() since myVariable is private. This class does not over-ride any
// functions so it should be using the myClass version upon each call using a yourClass
// object. Correct?
int main()
{
myClass myObject; // Creates a myClass object called myObject.
yourClass yourObject; // Creates a yourClass object called yourObject
yourObject.setMyVariable(); // Calls setMyVariable() through yourObject. This in turn calls the myClass version of it because
// there is no function definition for a yourClass version of this function. This means that this
// can indeed access myVariable, but only the myClass version of it (there isn't a yourClass
// version because myVariable is never inherited).
std::cout << yourObject.getMyVariable() << std::endl; // Uses the yourClass version of getMyVariable() which in turn
// calls the myClass version, thus it returns the myClass myVariable
// value. yourClass never has a version of myVariable Correct?
std::cout << myObject.getMyVariable() << std::endl; // Calls the myClass version of getMyVariable() and prints myVariable.
return 0;
}
void myClass::setMyVariable()
{
myVariable = 15; // Sets myVariable in myClass to 15.
}
int myClass::getMyVariable()
{
return myVariable; // Returns myVariable from myClass.
}
现在,理论依据是什么,我认为,这应该打印:15 15由于它只是始终使用的功能(因此使用在myClass MYVARIABLE)在myClass版本。 但是,奇怪的是,这种情况并非如此。 运行此程序打印的结果:15 0这使我怀疑,是我们实际上不仅继承MYVARIABLE,但我们也有能力与它周围乱? 显然,这是创建MYVARIABLE的替代版本不知何故否则为myClass的版本不会有一个0。 我们通过做这一切的确编辑MYVARIABLE的第二个副本。
是否有人可以解释这一切对我来说,这已经四分五裂我继承的理解。
Answer 1:
基本上,据我知道,当你创建一个基类与公共,保护,并在每个受保护的公共部分私人部分和变量/功能将得到继承到子类的适当部分(由类的子类中定义:私人基地,这将基地的所有公共和私有成员,并把它们纳入公共,私有改变公共字把他们所有的公共和其更改为保护把他们全部纳入保护)。
有这个说法有点混乱。
回想一下,继承在C ++类和结构定义。 单个对象(即实例)不从其他对象继承。 构建使用其他对象的对象被称为组合物 。
当一个类从另一个类继承,它得到的一切,从这个类,但继承的字段的访问级别可能会抑制继承中的使用。
此外,有3种继承的类: private
(这是默认值), protected
,和public
。 当一个子类继承了他们每个人都改变了一个类的属性和方法的访问级别。
如果我们为了用这种方式访问级别: public
, protected
, private
,从最小的保护,最受保护的,那么我们可以定义继承修饰符提高到至少水平,他们指定继承的类字段的访问级别,在派生类(即所述类继承)。
例如,如果类B
从类继承A
与protected
遗传修饰:
class B : protected A { /* ... */ };
那么所有从地里A
将至少具有protected
的水平B
:
-
public
领域成为protected
( public
级别提升到protected
), -
protected
领域保持protected
(同样的访问级别,所以没有在此修改) -
private
领域的留private
(访问级别已经是修改器上方)
Answer 2:
号派生类继承的基类的所有成员,包括私有的。 继承的类的对象具有了这些私有成员,但没有对他们的直接访问 。 它可以访问该可访问这些成员的基类的公共成员,但它(派生类)可能不具有这样的接入新成员函数:
class yourClass : public myClass
{
public:
void playByTheRules()
{
setMyVariable(); // perfectly legal, since setMyVariable() is public
}
void tamperWithMyVariable()
{
myVariable = 20; // this is illegal and will cause a compile-time error
}
};
Answer 3:
myObject
和yourObject
是两个不同的对象! 为什么他们应该分享什么?
想想这种方式:忘记继承和假设你有一类Person
有private int age;
和public void setAge (int age) {...}
然后,实例化两个对象:
Person bob;
Person bill;
bob.setAge(35);
你会想到比尔是35现在呢? 你不会的,对不对? 同样的,你的myObject
不共享其数据yourObject
。
在回答您的评论:
类yourClass
继承自myClass
。 这意味着这两个yourObject
和myObject
有自己的myVariable
,显然被定义后者,前者继承自myClass
。
Answer 4:
物理上,基类的每一个部件(包括成员函数)进入子类。 如果他们是私人无所谓。 如果你公开继承他们没关系/保护-LY /私人。 所以,在你的榜样, yourClass
包含所有三个getMyVariable()
setMyVariable()
和myVariable
。 这一切都是非常简单的,好吗?
重要的是我们如何能够访问它们。 这是当一个文件被您的系统上删除等。 所以,你应该先了解一个成员是不是有和成员在那里人迹罕至,但之间的区别。 现在假设所有继承发生公开。 然后,基类的所有公共成员在派生类中的public,protected成员protected和private成员不可访问。 他们是不可访问,而不是不存在的,因为可以有在基类保护和公共部分,其访问基类的私有成员的一些成员函数。 因此,我们需要通过基础的公共和保护的成员函数访问,其功能基的所有那些私有成员。 由于没有办法,我们可以确定哪个部件是由成员函数以简单的方式根据需要,我们包括在派生类的基类的所有私有成员。 所有这一切只是意味着在派生类,一个私有成员只能由通过基类的成员函数修改。
注:每个私有成员都可以访问,直接或间接地[通过这又是一个公共/受保护的成员函数调用另一个私有成员函数]由公共/保护meber功能,否则它已经没有用了。
所以,我们知道到现在基类的私有成员变量有其即对于其公共/受保护的成员函数的功能派生类中使用。 但是,他们不能直接在基类访问。
现在,我们把注意力转向私有/公有继承。 对于公有继承,这意味着所有基类的访问成员(即公众和受保护成员)不能比公众更宽松的水平。 因为,公众是最宽松水平,公共和保护成员保持公开。 但在保护和私有继承,两者分别成为protected和private在派生类中。 在矿井后一种情况下,因为所有这些成员都是私有的,它们不能被进一步层次链访问,但可以通过给定的派生类都是一样的访问。
因此,在派生类的每个基类成员的水平是它们在派生类级()和继承的类型(公用/被保护/私有)中的较小者。
相同的概念适用于类之外的功能。 对他们来说,private和protected成员都无法访问,但他们确实存在,并且可以通过公共成员函数访问。
并把你的情况下,最后一个例子, setMyvariable()
和getMyVariable()
可以访问myVariable
在派生类中。 但是,没有在派生类中指定的函数可以访问myVariable
。 修改你的类:
class myClass
{
public:
void setMyVariable();
int getMyVariable();
private:
int myVariable;
};
class yourClass : public myClass
{
public:
// void yourFunction() { myVariable = 1; }
/*Removing comment creates error; derived class functions can't access myVariable*/
};
另外:你可以添加例外继承类型也如私有继承除了成员作出派生类中公开。 但是,这是另一个问题完全。
Answer 5:
你永远不会调用myObject.setMyVariable()
所以myObject.getMyVariable()
将不会返回15。
private
并不意味着static
。
Answer 6:
后:
class yourClass : public myClass {};
还有只有一个成员变量 。 但也有通过名字来访问它的方法有两种: myClass::myVariable
和yourClass::myVariable
。
在这些表达式中,类名被称为命名类 。 要了解的第二个关键问题是, 访问权限适用于命名类和成员名称的组合 ; 不仅对成员名称,而不是变量本身。
如果一个成员在没有明确地具有命名类本提到的,则命名类是从表达对的左侧的类型推断.
或->
名为的构件(与this->
被暗示如果不存在这样的表达)。
此外,还有一些真正的四种可能的访问类型: public
, protected
, private
和禁止访问 。 你不能声明成员为无访问 ,但是当一个私有成员继承这种情况就出现了。
所有应用这一理论到您的例子:
- 该名
myClass::myVariable
是private
。 - 该名
yourClass::myVariable
没有访问 。
再次重申,只有真正一个变量,但它可能以两种不同的方式来命名,并且访问权限不同取决于所使用的名称。
最后,回到你原来的例子。 myObject
和yourObject
是不同的对象。 我想你打算写,或者你有足够的心理想象居然是这样的情况:
yourClass yourObject;
myClass& myObject = yourObject;
// ^^^
这意味着myObject
名称的基类部分yourObject
。 然后:
yourObject.setMyVariable();
该变量被设置为15
,所以
std::cout << myObject.getMyVariable() << std::endl;
将输出15
,因为确实是有只有一个变量。
Answer 7:
这可能有助于
#include<iostream>
using namespace std;
class A
{
int b;
};
class B : private A
{
};
int main()
{
C obj;
cout<<sizeof(obj);
return 0;
}
文章来源: Do Sub-Classes Really Inherit Private Member Variables?