曲径通幽论坛
标题: 继承基本概念与基类的访问控制 [打印本页]
作者: beyes 时间: 2011-8-24 11:13
标题: 继承基本概念与基类的访问控制
继承能够创建层次结构的分类。
可以定义一个通用类,并在该类中定义一些和一组类相关的公共特征,其他类则通过继承的方法以拥有该通用类的特性;进一步来说,继承之后的类又可以在自己的定义中增加各自独有的特征。
被继承的类称为基类;继承之后的类被称为派生类;同时一个派生类也可以作为其他派生类的基类。
继承的通用形式如下所示:
[C++] 纯文本查看 复制代码
class derived-class : access base-class {
// 新类内容
};
其中,access 是可选的,它的选项有 3 个:public, private 或者 protected 。
下面实例中将创建一个交通工具的基类,在基类中,描述了交通工具的一些共有的特征,然后再创建一个卡车和一个汽车的派生类,卡车和汽车不但拥有交通工具的共用特征,而且还拥有自己的一些独特的特征。
这里,继承时使用上面的 access 为 public 方式,这样表示:基类的所有共有成员也是派生类的公有成员。
示例代码:
[C++] 纯文本查看 复制代码
#include <iostream>
using namespace std;
//交通工具基类
class road_vehicle {
int wheels; //轮子
int passengers; //乘客
public:
void set_wheels(int num) { wheels = num; }
int get_wheels() { return wheels; }
void set_pass(int num) { passengers = num; }
int get_pass() { return passengers; }
};
//定义卡车派生类
class truck : public road_vehicle {
int cargo; //货物
public:
void set_cargo(int size) { cargo = size; }
int get_cargo() { return cargo; }
void show();
};
enum type {car, van, wagon};
//定义汽车派生类
class automobile : public road_vehicle {
enum type car_type;
public:
void set_type(type t) { car_type = t; }
enum type get_type() { return car_type; }
void show();
};
void truck::show()
{
cout << "wheels: " << get_wheels() << endl;
cout << "passengers: " << get_pass() << endl;
cout << "cargo capacity in cubic feet: " << cargo << endl; //每立方英尺可放多少货物
}
void automobile::show()
{
cout << "wheels: " << get_wheels() << endl;
cout << "passengers: " << get_pass() << endl;
cout << "type: ";
switch (get_type()) {
case van:
cout << "van\n";
break;
case car:
cout << "car\n";
break;
case wagon:
cout << "wagon\n";
}
}
int main()
{
truck t1, t2;
automobile c;
t1.set_wheels(18);
t1.set_pass(2);
t1.set_cargo(3200);
t2.set_wheels(6);
t2.set_pass(3);
t2.set_cargo(1200);
t1.show();
cout << "\n";
t2.show();
cout << "\n";
c.set_wheels(4);
c.set_pass(6);
c.set_type(van);
c.show();
return 0;
}
运行输出:$ ./vehicle
wheels: 18
passengers: 2
cargo capacity in cubic feet: 3200
wheels: 6
passengers: 3
cargo capacity in cubic feet: 1200
wheels: 4
passengers: 6
type: van
当一个类从另一个类继承时,基类的成员也成为了派生类的成员。如上面所说,派生类对基类成员的访问状态是由 public, private 或 protected 这 3 个控制符之一来指定。
如果派生类是 class 类型,那么在忽略访问控制符的情况下,编译器默认使用 private 。
如果派生类是 struct 类型,那么在忽略访问控制符的情况下,编译器默认使用 public 。
public 和 private 的区别
当使用 public 从基类继承时,基类中的所有公有成员都将成为派生类的公有成员。
当使用 private 从基类继承时,基类的所有成员将成为派生类的私有成员。
在所有情况下,基类的私有成员仍将保持为基类的私有成员,不能被派生类访问。
下面程序中,基类 base 的共有成员将成为派生类 derived 的公有成员,他们可以被程序的其他代码访问,但其私有成员不允许派生类直接访问(可通过继承下来的基类中的公有成员函数来访问):
[C++] 纯文本查看 复制代码
#include <iostream>
using namespace std;
class base {
int i, j;
public:
void set(int a, int b) { i = a; j = b; }
void show() { cout << i << " " << j << "\n"; }
};
class derived : public base {
int k;
public:
derived(int x) { k = x; }
void showk() { cout << k << "\n"; }
};
int main()
{
derived ob(3);
ob.set(1, 2); //通过继承基类的成员函数来访问基类的私有成员变量
ob.i = 10; //错误,无法直接访问!
ob.show();
ob.showk();
return 0;
}
去掉 ob.i = 10 后,可以通过编译,运行输出:
对比使用 privated 继承的情况(下面程序将不能通过编译):
[C++] 纯文本查看 复制代码
#include <iostream>
using namespace std;
class base {
int i, j;
public:
void set(int a, int b) { i = a; j = b; }
void show() { cout << i << " " << j << "\n"; }
};
//注意,基类的公有成员在派生类中是私有的
class derived : private base {
int k;
public:
derived(int x) { k = x; }
void showk() { cout << k << "\n"; }
};
int main()
{
derived ob(3);
ob.set(1, 2); //错误!使用 private 继承,set()已被认为是派生类中的私有成员
ob.show(); //错误!同 ob.set(1, 2)
ob.showk();
return 0;
}
记住关键一点:
当派生类使用 private 继承基类时,基类的公有成员就将成为派生类的私有成员。这意味着,他们仍然可以被派生类的成员访问,但不能被程序的其他部分访问!
修改上面程序如下:
[C++] 纯文本查看 复制代码
#include <iostream>
using namespace std;
class base {
int i, j;
public:
void set(int a, int b) { i = a; j = b; }
void show() { cout << i << " " << j << "\n"; }
};
//注意,基类的公有成员在派生类中是私有的
class derived : private base {
int k;
public:
derived(int x) { k = x; }
void showk() { cout << k << "\n"; }
void setd(int x, int y) { set(x, y); }
void showd() { show(); }
};
int main()
{
derived ob(3);
ob.showk();
ob.setd(10, 9);
ob.showd();
return 0;
}
运行输出:在上面程序中,我们为派生类添加了两个函数 setd() 和 showd(),我们就在这两个函数内访问了从基类中继承下来的函数 set() 和 show() ,因为 set() 和 show() 此时已经变为了派生类中的私有成员函数。
欢迎光临 曲径通幽论坛 (http://www.groad.net/bbs/) |
Powered by Discuz! X3.2 |