赞
踩
:体现了由简单到复杂的过程。保持原有特性的基础进行扩展,增加功能。
通过继承对类进行分层,提供类型和派生类的关系。
也就是基类和派生类
struct A{} 当做一个数据集合来看待。只有数据
classB{}当做一个对象来看待。有数据和方法
保护属性,在继承关系中可以看做是共有属性。
无论采取何种继承方式,我们都可以访问基类的保护和公有。
//struct的公有继承。
struct A{}
structB:A{}
//class私有继承
classA{}
classB:A{}
//class继承struct
structA{}
classB:A //私有继承。
//struct继承class
classA{}
structB:A{}
下面的程序,能否说派生类继承基类的两个成员,即派生类现在有四个成员?
这种说法肯定是错误的,不能根据设计的形式来谈论内存中的存在形式。
准确来说,派生类中有三个成员,分别是隐藏的基类对象,c和d,这个隐藏的基类对象中包含了a,b两个成员。
如下:
class object
{
public:
int a;
int b;
};
class Base:public Object
{
public:
int c;
int d;
};
示例:对于派生类的fun()函数,哪条语句不能通过编译通过?
很明显:ax编译不通过。
原因:由于fun()函数为派生类的公有方法,所以可以访问自己的成员,而继承下来的基类隐藏对象也属于派生类,所以可以访问隐藏对象的保护属性和公有属性。
很明显,ax还是不能编译。
原因:由于是私有方式继承下来,那么隐藏的的基类对象的权限和自身的private成员权限相同,既可以访问自己的私有成员,也可以访问隐藏基类对象的公有成员和保护成员。
隐藏基类对象的权限和bx是相同的。都属于private
派生类对象可以访问继承对象的保护和公有属性
具名对象为私有时,只能访问这个具名对象中的公有属性。
class B; class A { private: int ax; protected: int ay; public: int az; }; class B :public A //B可以访问A的公有和保护属性 { private: int bx; protected: int by; public: int bz; }; class C :public B //C可以访问B的公有和保护属性 { private: int cx; protected: int cy; public: int cz; void fun() { cx = cy = cz = 10; bx = by = bz = 20;//访问不到bx ax = ay = az = 30;//访问不到ax } };
B公有继承A类,C类对象可以访问A类的公有和保护
B类对象对A对象的访问不论私有公有,都只能访问保护和公有
void fun()
{
cx = cy = cz = 10;
bx = by = bz = 20;//访问不到bx,
ax = ay = az = 30;//访问不到ax ,ay,az
}
B私有继承A类,C类对象访问不到A的任何一个属性
C类对象对B类的访问不论私有公有,都只能访问保护和公有
A aa;
class A { private: int ax; protected: int ay; public: int az; A() { ax = ay = az = 0; } }; class B :public A { private: int bx; A aa; protected: int by; public: int bz; };
在公有继承中,派生类对象可以对基类对象进行赋值
比如:
class Object { private: int value; public: Object(int x = 0) :value(x) { cout << "CreateObject:" << this << endl; } ~Object() { cout << "DestoryObject:" << this << endl; } }; class Base :public Object { private: int num; public: Base(int x = 0) :num(x),Object(x+10) { cout << "CreateBase:" << this << endl; } ~Base() { cout << "DestoryBase:" << this << endl; } };
class
int main()
{
Object obja(100);
Base base(10);
obja = base;
}
CreateObject:0073F6F8 //创建obja对象
CreateObject:0073F6E8 //创建隐藏基类对象
CreateBase:0073F6E8//创建base对象
DestoryBase:0073F6E8
DestoryObject:0073F6E8
DestoryObject:0073F6F8
Base(int x = 0) :num(x),Object(x+10)
//创建隐藏基类对象
Base(int x = 0) :num(x),Object(x+10)
//隐藏基类对象初始化完,接着派生类base对象中num被初始化为10
obja = base;
int main()
{
Object obja(100);
Base base(10);
// obja = base;
Object* op = &base;
// Object& obja = base;
}
引用其实就是基类引用派生类中隐藏基类对象中的值。
如:Object& obja = base; ------》 obja是隐藏基类对象的别名。
当派生类中的成员属性和基类中的成员属性同名时,派生类中的成员属性会覆盖掉基类中的成员属性。
class B; class A { protected: int ax; public: A() :ax(0) {}; ~A() {}; }; class B:public A { private: int ax; public: B() :ax(10) {} void fun() { ax = 100; } };
int main()
{
B b;
b.fun();
}
先对隐藏基类对象中ax初始化为0,再对派生类B,b对象中ax初始化为10
调用b.fun() 只对派生类中的ax进行赋值,因为基类同名的成员属性被覆盖了。
当加上作用域,则就是给作用域内中的类的成员属性赋值。
void fun()
{
// ax = 100;
A::ax = 100;
// B::ax = 200;
}
class A
{
protected:
int ax;
public:
A() :ax(0) {};
~A() {};
void fun() { cout << "A::fun()" << endl; }
};
int main()
{
B b;
//b.fun();
b.A::fun();//要访问必须基类公有方法,必须是公有继承。
}
外部函数在私有继承下,无法访问基类的任何成员不论公有,私有还是保护
只有在公有继承下,才可以访问基类的公有成员。
派生类如何直接访问隐藏基类对象的私有成员属性。直接将派生类设置为友元即可。
Object(const Object& obj) : value(obj.value)
{
cout << "Copy Create Object: " << this << endl;
}
Base(const Base& b) : num(b.num)
{
cout << "Copy Create Base: " << this << endl;
}
int main()
{
Base b1(10);
Base b2(b1); //
}
在b2(b1)时,调用的基类对象的构造函数而不是拷贝构造函数
因此无法完成对b2中隐藏基类对象的的拷贝。需要改进
对派生类拷贝构造函数改进后,就可以拷贝到隐藏基类对象中。
//拷贝构造函数 Object(const Object& obj):value(obj.value) { cout << "Copy Object:" << this << endl; } ~Object() { cout << "DestoryObject:" << this << endl; } }; //拷贝构造函数 Base(const Base& b) :num(b.num), Object(b) { cout << "Copy Base:" << this << endl; } ~Base() { cout << "DestoryBase:" << this << endl; } };
int main()
{
Base b1(10);
Base b2(b1); //
}
那么为什么 这样写: Base(const Base& b) :num(b.num), Object(b)。就可以完成对隐藏基类对象的赋值。
原因是因为,派生类对象可以对基类对象进行赋值,上面讲过,指针和引用是同样适用的。
千万不要在派生类的拷贝构造函数中调用基类的拷贝构造函数。
原因:调用这个基类对象,只会构造出来一个无名对象,和我们目标的隐藏基类对象无关,所以拷贝构造万就被析构了,没啥用。
Base(const Base& base) : num(base.num) //, Object(base)
{
Object::Object(base);
cout << "Copy Create Base: " << this << endl;
}
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。