2008 iis 网站自己开发app要钱吗
2008 iis 网站,自己开发app要钱吗,建设商业门户网站的重要,成都的网站建设公司私有继承
在C中#xff0c;私有继承是一种继承方式#xff0c;它定义了一个私有派生类#xff0c;也称为派生类。私有继承意味着派生类继承了基类的所有成员#xff0c;但这些成员在派生类中是私有的#xff0c;对外部不可见。
要进行私有继承请使用private关键字#…私有继承
在C中私有继承是一种继承方式它定义了一个私有派生类也称为派生类。私有继承意味着派生类继承了基类的所有成员但这些成员在派生类中是私有的对外部不可见。
要进行私有继承请使用private关键字或者不使用任何关键字因为private是默认值因此省略访问限定符也将导致私有继承
格式如下
class 派生类名:private 基类名
{
}或者class 派生类名:基类名
{
} 使用私有继承时只能在派生类的方法里使用基类的方法
私有继承允许使用类名和作用域解析运算符来调用基类的方法
我们看个例子
#includeiostream
using namespace std;
class AA
{
private:int a_;
public:AA(int a):a_(a){}void A(){cout a_ endl;}
};
class BB :AA
{
private:int b_;
public:BB(int a,int b):AA(a),b_(b){}void B(){A();//可以AA::A();//可以}
};int main()
{BB r(2, 3);r.B();} 我们怎么通过派生类访问基类对象呢当然是用强制类型转换
我们看个例子
#includeiostream
using namespace std;
class AA
{
private:int a_;
public:AA(int a):a_(a){}void A(){cout a_ endl;}
};
class BB :AA
{
private:int b_;
public:BB(int a,int b):AA(a),b_(b){}AA B(){return (AA)*this;//派生类强制转换为基类}
};int main()
{BB r(2, 3);AA tr.B();t.A();}
在私有继承中未进行显式类型转换的派生类引用或指针无法赋值给基类的引用或指针
#includeiostream
using namespace std;
class AA
{
private:int a_;
public:AA(int a):a_(a){}void A(){cout a_ endl;}
};
class BB :AA
{
private:int b_;
public:BB(int a,int b):AA(a),b_(b){}};int main()
{BB r(2, 3);AA t r;//这是不行的AA* y r;//这是不行的
}
保护成员
class A
{
protected:
int a;
} 和私有成员类似受保护的成员对于类的用户来说是不可访问的和公有成员类似受保护的成员对于派生类的成员和友元来说是可访问的。派生类的成员或友元只能通过派生类对象来访问基类的受保护成员。派生类对于个基类对象中的受保护成员没有任何访问特权。 为了理解最后一条规则请考虑如下的例子
class Base
{
protected:
int prot_mem; // protected成员
};
class Sneaky:public Base{
friend void clobber(Sneaky) // 能访问 Sneaky::prot_mem
friend void clobber(Base) // 不能访问Base::prot mem
int j; // j默认是private
};
//正确clobber能访问Sneaky对象的private和protected成员
void clobber(Sneaky s)
{s.i s.prot_mem 0}
// 错误clobber不能访问Base的protected成员
void clobber(Base b)
{b.prot_mem0;}
如果派生类(及其友元)能访问基类对象的受保护成员则上面的第二个clobber(接受一个Base)将是合法的。该函数不是Base的友元但是它仍然能够改变一个Base对象的内容。
如果按照这样的思路则我们只要定义一个形如 Sneaky 的新类就能非常简单地规避掉protected提供的访问保护了。
要想阻止以上的用法我们就要做出如下规定即派生类的成员和友元只能访问派生类对象中的基类部分的受保护成员对于普通的基类对象中的成员不具有特殊的访问权限。 保护继承
保护继承是私有继承的变体。保护继承在列出基类时使用关键字protected:
class 派生类名:protected 基类名
{
}
使用保护继承时基类的公有成员和保护成员都成为派生类的保护成员。
和私有继承一样基类的接口在派生类中也是可用的但是在继承层次结构之外是不可用的。当从派生类派生出另一个类时私有继承和保护继承的区别就体现出来了。
使用私有继承时第三代类将不能使用基类的接口这是因为基类的公有方法在派生类中变成私有方法使用保护继承时基类的公有方法在第二代中变成受保护的因此第三代派生类可以使用它们。
三种继承方式的比较
公有继承(public)继承、私有继承(private)、保护继承(protected)是常用的三种继承方式。 1.公有继承(public) 公有继承的特点是基类的公有成员和保护成员作为派生类的成员时它们都保持原有的 状态而基类的私有成员仍然是私有的不能被这个派生类的子类所访问。 2.私有继承(private) 私有继承的特点是基类的公有成员和保护成员都作为派生类的私有成员并且不能被这 个派生类的子类所访问。 3.保护继承 保护继承的特点是基类的所有公有成员和保护成员都成为派生类的保护成员并且只能 被它的派生类成员函数或友元访问基类的私有成员仍然是私有的。 三种不同继承方式的基类特性和派生类特性
公有继承保护继承私有继承公有成员变为派生类的公有成员派生类的保护成员派生类的私有成员保护成员变成派生类的保护成员派生类的保护成员派生类的私有成员私有成员变为只能通过基类接口访问只能通过基类接口访问 只能通过基类接口访问 能否隐式向上转换是是但只能在基类里否 注隐式向上转换:意味着无需进行显式类型转换就可以将基类指针或引用指向派生类对象 对于公有继承方式 1.基类成员对其对象的可见性公有成员可见其他不可见。这里保护成员同于私有成员。 2.基类成员对派生类的可见性公有成员和保护成员可见而私有成员不可见。这里保护成员同于公有成员。 3.基类成员对派生类对象的可见性公有成员可见其他成员不可见。 所以在公有继承时派生类的对象可以访问基类中的公有成员派生类的成员函数可以访问基类中的公有成员和保护成员。这里一定要区分清楚派生类的对 象和派生类中的成员函数对基类的访问是不同的。 对于私有继承方式 1.基类成员对其对象的可见性公有成员可见其他成员不可见 2.基类成员函数对派生类的可见性公有成员和保护成员是可见的而私有成员是不可见的。 3.基类成员对派生类对象的可见性所有成员都是不可见的。 所以在私有继承时基类的成员只能由直接派生类访问而无法向下继承。 对于保护继承方式 这种继承方式与私有继承方式的情况相同。两者的区别仅在于对派生类的成员而言而对于基类成员有不同的可见性。(可见性也就是可访问性)。 关于可访问性还有另外一种说法。这种规则中称派生类的对象对基类访问为水平访问称派生类的派生类对基类的访问为垂直访问。 1 #includeiostream2 class A{3 private:4 int privatedataA;5 protected:6 int protecteddataA;7 public:8 int publicdataA;9 };
10 //基类A的派生类B(公有继承)
11 class B :public A{
12
13 public:
14 void funcA()
15 {
16 int b;
17 b privatedataA;
18 //错误基类中的私有成员在派生类中不可见
19 b protecteddataA;
20 //正确基类的保护成员在派生类中是保护成员
21 b publicdataA;
22 //正确基类的公共成员在派生类是公共成员
23 }
24 };
25 //基类A的派生类C 私有继承
26 class C :private A{
27
28 public:
29 void funcA()
30 {
31 int c;
32 c privatedataA;
33 //错误基类中的私有成员在派生类中不可见
34 c protecteddataA;
35 //正确基类的保护成员在派生类中是私有成员
36 c publicdataA;
37 //正确基类的公共成员在派生类是私有成员
38 }
39 };
40 //基类A的派生类D 保护继承
41 class D :protected A{
42 public:
43 void funcA()
44 {
45 int d;
46 d privatedataA;
47 //错误基类中的私有成员在派生类中不可见
48 d protecteddataA;
49 //正确基类的保护成员在派生类中是保护成员
50 d publicdataA;
51 //正确基类的公共成员在派生类是保护成员
52 }
53 };
54 void main()
55 {
56 int value;
57 B objB;
58 value objB.privatedataA;//错误基类的私有成员在派生类不可见对对象不可见
59 value objB.protecteddataA;//错误基类的保护成员在派生类中是保护成员对对象不可见
60 value objB.publicdataA;//错误基类的公共成员在派生类中是公共成员对对象可见
61
62 C objC;
63 value objC.privatedataA;//错误基类的私有成员在派生类不可见对对象不可见
64 value objC.protecteddataA;//错误基类的保护成员在派生类中是私有成员对对象不可见
65 value objC.publicdataA;//错误基类的公共成员在派生类中是私有成员对对象不可见
66
67 D objD;
68 value objD.privatedataA;//错误基类的私有成员在派生类不可见对对象不可见
69 value objD.protecteddataA;//错误基类的保护成员在派生类中是保护成员对对象不可见
70 value objD.publicdataA;//错误基类的公共成员在派生类中是保护成员对对象不可见
71 system(pause);
72 } 公有私有和受保护继承 某个类对其继承而来的成员的访问权限受到两个因素影响一是在基类中该成员的访问说明符二是在派生类的派生列表中的访问说明符。
举个例子考虑如下的继承关系 class Base {
public:
void pub mem()
protected:
int prot_mem;
private:
char priv_mem;};
struct Pub_Derv : public Base {
//正确派生类能访问protected成员
int f() { return prot mem; }
//错误private成员对于派生类来说是不可访问的
char g() { return priv_mem; }
}
struct Priv_Derv : private Base {
// private不影响派生类的访问权限
int f1() const{ return prot_mem;} 派生访问说明符对于派生类的成员及友元能否访问其直接基类的成员没什么影响对 基类成员的访问权限只与基类中的访问说明符有关。
Pub_Dery和Priv_Derv都能须问613 受保护的成员prot_mem同时它们都不能访问私有成员priv_mem。
派生访问说明符的目的是控制派生类用户(包括派生类的派生类在内)对于基类成前的访问权限 Pub_Dery d1; // 继承自Base的成员是public的
Priv_Derv d2;//继承自Base的成员是private的
dl.pub_mem()// 正确pub_mem在派生类中是public的
d2.pub_mem()//错误pub_mem在派生类中是private的 Pub_Derv和Priv_Derv都继承了pub_mem函数。
如果继承是公有的 则成员将遵循其原有的访问说明符此时d1可以调用pub_mem。
在Priv_Derv中Base 的成员是私有的因此类的用户不能调用pub_mem。
派生访问说明符还可以控制继承自派生类的新类的访问权限 struct Derived_from_Public : public Pub_Derv{//正确Base::prot mem在Pub_Derv中仍然是protected的
int use_base
{return prot mem;}
};struct Derived_from_Private: pubiic Priv_Derv {
// 错误Base::prot_mem在Priv_Derv中是private的
int use_base()
{return prot_mem;}
}; Pub_Derv 的派生类之所以能访问Base的prot_mem成员是因为该成员在Pub Dery中仍然是受保护的。相反Priv Derv 的派生类无法执行类的访问对于它们来说Priv_Derv继承自Base的所有成员都是私有的。
假设我们之前还定义了一个名为Prot_Derv的类它采用受保护继承则Base的所有公有成员在新定义的类中都是受保护的。Prot_Derv的用户不能访问pub mem但是Prot_Derv的成员和友元可以访问那些继承而来的成员。
派生类向基类转换的可访问性
派生类向基类的转换是否可访问由使用该转换的代码决定同时派生类的派生访问说明符也会有影响。假定D继承自B
只有当D公有地继承B时用户代码才能使用派生类向基类的转换如果D继承B的方式是受保护的或者私有的则用户代码不能使用该转换。不论D以什么方式继承BD的成员函数和友元都能使用派生类向基类的转换派生类向其直接基类的类型转换对于派生类的成员和友元来说永远是可访问的。如果D继承B的方式是公有的或者受保护的则D的派生类的成员和友元可以使用D向B的类型转换反之如果D继承B的方式是私有的则不能使用
对于代码中的某个给定节点来说如果基类的公有成员是可访问的则派生类Tp 向基类的类型转换也是可访问的反之则不行。 访问控制与继承 不考虑继承的话我们可以认为一个类有两种不同的用户普通用户和类的实现者 其中普通用户编写的代码使用类的对象这部分代码只能访问类的公有(接口)成员实现者则负责编写类的成员和友元的代码成员和友元既能访问类的公有部分也能访问类的私有(实现)部分。 如果进一步考虑继承的话就会出现第三种用户即派生类。基类把它希望派生类能够使用的部分声明成受保护的。普通用户不能访问受保护的成员而派生类及其友元仍旧不能访问私有成员。 和其他类一样基类应该将其接口成员声明为公有的同时将属于其实现的部分分成两组一组可供派生类访问另一组只能由基类及基类的友元访问。对于前者应该声明为受保护的这样派生类就能在实现自己的功能时使用基类的这些操作和数据对于后者应该声明为私有的。 友元与继承
就像友元关系不能传递一样友元关系同样也不能继承。基类的友元在访问派生类成员时不具有特殊性类似的派生类的友元也不能随意访问基类的成员
class Base
{
protected:
int prot_mem; // protected成员
// 添加friend声明其他成员与之前的版本一致
friend class Pal; // Pal在访问Base的派生类时不具有特殊性
};
class Sneaky:public Base{
friend void clobber(Sneaky) // 能访问 Sneaky::prot_mem
friend void clobber(Base) // 不能访问Base::prot mem
int j; // j默认是private
};class Pal {
public:
int f(Base b) { return b.prot_mem; } //正确Pal是Base的友元int f2(Sneaky s) { return s.j;} //错误Pal不是Sneaky的友元
// 对基类的访问权限由基类本身控制即使对于派生类的基类部分也是如此
int f3(Sneaky s) { return s.prot mem;} // 正确Pal是Base的友元
}; 如前所述每个类负责控制自己的成员的访问权限因此尽管看起来有点儿奇怪但f3 615确实是正确的。Pal是Base的友元所以Pal能够访问Base对象的成员这种可访问性包括了Base对象内嵌在其派生类对象中的情况。
当一个类将另一个类声明为友元时这种友元关系只对做出声明的类有效。对于原来那个类来说其友元的基类或者派生类不具有特殊的访问能力
// D2对Base的protected和private成员不具有特殊的访问能力
class D2 : public Pal {
public:
int mem(Base b)
{ return b.prot_mem; } //错误友元关系不能继承 不能继承友元关系每个类负责控制各自成员的访问权限。 改变个别成员的可访问性
有时我们需要改变派生类继承的某个名字的访问级别通过使用using声明可以达到这一目的
class Base
{
public:
std::size_t size() const { return n;}
protected:
std::size_t n;// 注意private继承
class Derived : private Base {public://保持对象尺寸相关的成员的访问级别
using Base::size;protected:
using Base::n;
}; 因为Derived 使用了私有继承所以继承而来的成员size和n(在默认情况下)是Derived的私有成员。
然而我们使用using声明语句改变了这些成员的可访问性。改变之后Derived的用户将可以使用size成员而Derived的派生类将能使用通过在类的内部使用using 声明语句我们可以将该类的直接或间接基类中的任备可访问成员(例如非私有成员)标记出来。
using声明语句中名字的访问权限由该声明语句之前的访问说明符来决定。
如果一条using 声明语句出现在类的private部分则该名字只能被类的成员和友元访问如果using声明语句位于public部分则类的所有用户都能访问它如果 using 声明语句位于protected 部分则该名字对于成员、友元和派生类是可访问的。 派生类只能为那些它可以访问的名字提供using声明。 默认的继承保护级别
我们曾经介绍过使用struct和class关键字定义的类具有不同的默认访问说明符。
类似的默认派生运算符也由定义派生类所用的关键字来决定。
默认情况下使用class关键字定义的派生类是私有继承的而使用 struct 关键字定义的派生类是公有继承的
class Base { /*...*/}
struct D1: Base{ /*...*/} // 默认 public继承
class D2 : Base{/*..*/} // 默认 private 继承 人们常常有一种错觉认为在使用struct关键字和class关键字定义的类之间还有更深层次的差别。事实上唯一的差别就是默认成员访问说明符及默认派生访问说明符除此之外再无其他不同之处。 一个私有派生的类最好显式地将private声明出来而不要仅仅依赖于默认的设置。显式声明的好处是可以令私有继承关系清晰明了不至于产生误会。
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/88772.shtml
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!