c++公有继承的问题
public继承并不是说不继承父类的private成员,是继承的,只是在子类的成员函数中无法访问父类的私有成员.
C++中的公有继承和私有继承
派生类不能继承基类的私有成员。
积累的构造函数和析构函数也不能继承。
对于你说的这句话“派生类中的构造函数还要写出基类构造函数中需要的参数”你说的是继承中出现的一个规定:
c++ 中规定 当派生类函数构造函数初始化时,必须同时对基类构造函数初始化。请看这个例子:然后你运行一下,然后再考虑一下,
#include
class Counter
{
public:
Counter(){val=0;cout<<"Default Constructor of Counter"< Counter(int x){val=x;cout<<"Coustructor of Counter:"< ~Counter(){cout<<"Destructor of counter:"< private: int val; }; class Example { public: Example(){ val=0;cout<<"Default Constructor of Example"< Example(int x): c2(x){val=x,cout<<"Constructor of Example:"< ~Example(){cout<<"Destructor of Example:"< void Print(){cout<<"value="< private: Counter c1,c2; int val; }; void main() { Example e1,e2(4); e2.Print(); } 公有继承,派生类类继承父的保护成员时,这个成员对于派生类来说也是保护的,可以理解成这个成员就是派生类的保护成员 根据保护成员的定义 是不能在类外访问的.保护成员访问权限:从类的外部(指在普通函数或其它类的成员函数中)不能对它们访问 public公有继承 protected保护继承 private私有继承 我们知道类的private和protected成员,在类外是不可以使用的.只有public成员可以在类外直接使用. 公有继承时,基类的private成员派生类也不可用,基类的public和protected成员在派生类中可直接使用.继承过来(变成派生类相应的public和protected成员)只有public成员在派生类外可以直接使用. 保护继承时,基类的private成员仍为有私有.基类的public和protected成员变成派生类的protected成员,这时在派生类外也不能直接使用原基类的public成员 私有继承时,基类的private成员仍为有私有.基类的public和protected成员将变成派生类的private成员. 举个例子. class A { public: int m_nTelNum; protected: int m_nAge; private: int m_nMoney; }; class B:public A { void SetTelNum(int nTelNum) { m_nTelNum=nTelNum; } void SetAge(int nAge) { m_nAge=nAge; } void SetMoney(int nMoney) { m_nMoney=nMoney;//这里就出现错误,因为基类的private成员不能用. } }; B objB;//创建B类的对象objB objB.m_nTelNum=123456;//可以 objB.m_nAge=30;//错误.public继承中基类的protected在派生类中是protected objB.m_nMoney=100;//更错误,在派生类中都不可以直接使用.在类外就更不能了. class C:protected A { void SetTelNum(int nTelNum) { m_nTelNum=nTelNum; } void SetAge(int nAge) { m_nAge=nAge; } void SetMoney(int nMoney) { m_nMoney=nMoney;//这里就出现错误,因为这是e79fa5e98193e59b9ee7ad9431333337383932基类的private成员不能用. } }; C objC;//创建C类的对象objC objC.m_nTelNum=123456;//注意这里和public的区别,这里错误,m_nTelNum变成了C类的protected成员 objC.m_nAge=30;//错误.protected继承中基类的protected在派生类中是protected,这与public同相 objC.m_nMoney=100;//更错误,在派生类中都不可以直接使用.在类外就更不能了. class D:private A { void SetTelNum(int nTelNum) { m_nTelNum=nTelNum; } void SetAge(int nAge) { m_nAge=nAge; } void SetMoney(int nMoney) { m_nMoney=nMoney;//这里就出现错误,因为这是基类的private成员不能用. } }; D objD;//创建D类的对象objD objD.m_nTelNum=123456;//错误,m_nTelNum变成了D类的private成员 objD.m_nAge=30;//错误.private继承中基类的protected在派生类中是private objD.m_nMoney=100;//更错误,在派生类中都不可以直接使用.在类外就更不能了. 从例子来看,三种继承从派生类内部引用来看好像没有区别,只在类外引用时表现不同.现在还看不出public和protected继承的区别 那再看一个例子. class E:public B { void SetTelNum(int nTelNum) { m_nTelNum=nTelNum;//可以 因为这是B的公有成员 } void SetAge(int nAge) { m_nAge=nAge;//可以 因为这是B的保护成员,现成变成E的protected成员 } void SetMoney(int nMoney) { m_nMoney=nMoney;//这个肯定不可以! } }; E objE;// objE.m_nTelNum=123456;//可以 //其它的两个就不能用了. class F:public C { void SetTelNum(int nTelNum) { m_nTelNum=nTelNum;//可以 因为这是C的保护成员,这里与public继承已经有区别但还没有表现出来 } void SetAge(int nAge) { m_nAge=nAge;//可以 因为这是C的保护成员,现成变成E的protected成员 } void SetMoney(int nMoney) { m_nMoney=nMoney;//这个肯定不可以! } }; F objF; objF.m_nTel=123456;//错误,因为这是F的保护成员.注意与E类区别 class G:public D { void SetTelNum(int nTelNum) { m_nTelNum=nTelNum;//不可以 因为这是D的private成员,注意这里区别 } void SetAge(int nAge) { m_nAge=nAge;//不可以 因为这是D的private成员,注意区别 } void SetMoney(int nMoney) { m_nMoney=nMoney;//这个肯定不可以! } }; //那G在类外就没有了可以引用的继承过来成员了! //这些继承方式是很难理解的.最好的办法就是多写代码去试. 在公有继承的情况下,基类的public部分等于派生类的public部分,此时派生类的成员或对象均能被访问;基类的protected部分等价于派生类的protected部分,派生类的成员可以进行访问,而派生类的对象不能进行访问;对于基类的private部分,无论是派生类的成员或对象都无法进行访问.由此可见,当类的成员是protected时,除了允许本身的成员函数访问之外,还允许派生类对这些成员进行访问.当类的成员是private时,则不能继承对成员的访问. 在公有继承中,派生类的对象可以访问基类中的public成员,派生类的成员函数可以访问基类中的public和protected成员. 不可以. 继承方式影响基类中标识符的访控特性在子类中所发生的变化. 访控限定符 访控属性 基类 子类 外部 友元 ———————————————- public 公有成员 OK OK OK OK protected 保护成员 OK OK No OK private 私有成员 OK No No OK 每个类控制它所定义的成员的访问权限,派生类可以进一步限制但不能放松对所继承的成员的访问.基类中的private成员只有基类和基类的友元可以访问,派生类不能访问基类的private成员,即使是public继承.所谓的派生列表中的访问标号(public、protected和private)只是决定基类的public和protected成员在派生类中的访问标号!如此例中的A::b在B中为protected.就是说你说的那句“公有继承中,基类的公有成员和保护成员,私有成员在派生类中依然是公有成员保护成员和私有成员.”应该去掉私有成员,就是对的了. 公有继承有利于多态实现 私有继承有利于封装组合 呵呵 我猜的 继承技术是面向对象编程的主要特征。面向对象编程语言引入继承机制,可以实现代码重用,提高编程效率。C#只支持单继承,即一个派生类只能有一个基类。 类的继承性是指一个类定义既可以具有其他类的数据成员、属性成员、方法成员等,也可以使其他类具有自己的数据成员、属性成员、方法成员等。在类的继承中,被继承的类叫基类或父类,继承的类叫派生类或子类。 派生类通常定义的语法格式为: public class 派生类名称 : 基类名称{类体} public:访问控制修饰符,访问控制修饰符可以是public、protected和private。通常都使用public以保证类的开放性,并且public可以省略,因为类定义的访问控制默认为是pulbic。 “:基类名称”:表示所继承的类。 在类的继承中,作为基类的数据成员通常使用protected修饰符,而不使用private修饰符。因为如果在基类中使用private修饰符声明数据成员,则其成员将不允许派生类成员访问,而protected修饰符,既能保证数据成员不被直接访问,又允许其派生类成员访问。 在创建派生类对象时,调用构造函数的顺序是先调用基类构造函数,再调用派生类的构造函数,以完成为数据成员分配内存空间并进行初始化的工作。 如果派生类的基类本身是另一个类的派生类,则构造函数的调用次序按由高到低顺序依次调用。例如,假设A类是B类的基类,B类是C类的基类,则创建C类对象时,调用构造函数的顺序为,先调用A类的构造函数,再调用B类的构造函数,最后调用C类的构造函数。 向基类构造函数传递参数,必须通过派生类的构造函数实现,其格式如下: public 派生类构造函数名(形参列表):base(向基类构造函数传递的实参列表){ } “base”是C#关键字,表示调用基类的有参构造函数。 传递给基类构造函数的“实参列表”通常包含在派生类构造函数的“形参列表”中。 密封类是不允许其他类继承的类。密封方法是不允许派生类重载的方法 定义密封类与密封方法需要使用sealed关键字,定义密封类的格式为: 访问修饰符 sealed class 类名称{ } 定义密封方法的格式为: 访问修饰符 sealed 返回类型 方法名称(参数列表){ } 多态性就是指在程序运行时,执行的虽然是一个调用方法的语句,却可以根据派生类对象的类型不同完成方法的不同的具体实现。 在类的继承中,C#允许在基类与派生类中声明具有同名的方法,而且同名的方法可以有不同的代码,也就是说在基类与派生类的相同功能中可以有不同的具体实现,从而为解决同一问题提供多种途径。 要实现继承的多态性,在类定义方面,必须分别用virtual关键字与override关键字在基类与派生类中声明同名的方法,在具体实现上通常是通过传递对象的途径,并且通常基类有两个以上的派生类,或者基类的派生类其下又有派生类。 基类中的声明格式: public virtual 返回类型 方法名称(参数列表){ } 派生类中的声明格式: public override 返回类型 方法名称(参数列表){ } 其中,基类与派生类中的方法名称与参数列表必须完全一致。 在派生类中声明与基类同名的方法,也叫方法重载。在派生类重载基类方法后,如果想调用基类的同名方法,可以使用base关键字。在派生类定义中调用基类方法的格式为: base 基类方法名称(参数列表); 抽象类是指基类的定义中声明不包含任何实现代码的方法,实际上就是一个不具有任何具体功能的方法。这样的方法唯一的作用就是让派生类重写。在基类定义中,只要类体中包含一个抽象方法,该类即为抽象类。在抽象类中也可以声明一般的虚方法。声明抽象类与抽象方法均需使用关键字abstract,抽象方法不是一般的空方法,抽象方法声明时,没有方法体。 抽象方法与虚方法的作用相同,两者均是实现多态的基础,因而两者均允许派生类重载。只不过对于基类中的抽象方法,在其派生类中要求必须重写,而虚方法则不要求一定重写。抽象方法一般应用于基类中的该方法不应有具体实现功能,而虚方法则应用于基类中的该方法应该有具体的实现功能。 在C#中,Array类是一个抽象类,该类提供创建、操作、搜索和排序数组的方法,因而在公共语言运行库中用作所有数组的基类。 在C#中,Math类是一个密封类,该类为三角函数、对数函数和其他通用数学函数提供常数和静态方法。Convert类也是一个密封类,该类将一个基本数据类型转换为另一个基本数据类型。 会调用构造函数,先调用基类的构造函数,再调用派生类的C++的 问题 公有继承
C++中。public,private,protected,用哪种继承方式好?
什么是公有继承,有什么特点
C++中公有继承方式下,基类的保护字段可被外界访问吗
关于公有继承
C++中的公有继承与私有继承
继承?继承的实现,定义类的格式,并举例说明
C++,继承