1. 继承方式基础知识
在C++中,通过继承来实现代码的复用是一种非常常见的编程技巧。继承方式有三种:公有继承、私有继承和保护继承。
1.1 公有继承
公有继承是以 public 的方式继承基类的,这意味着派生类可以访问基类中的 public 成员,但不能访问基类中的 protected 成员和 private 成员。下面是一个公有继承的例子:
class BaseClass {
public:
int public_member;
protected:
int protected_member;
private:
int private_member;
};
class DerivedClass : public BaseClass {
};
在这个例子中, DerivedClass 直接从 BaseClass 继承而来,派生类可以访问基类中的 public 成员,因此可以使用 public_member。但是,派生类不可以访问基类的 protected_member 和 private_member 成员。
1.2 私有继承
私有继承是以 private 的方式继承基类的,这意味着派生类不能直接访问基类中的任何成员,基类成员的访问权限由派生类的成员函数决定。下面是一个私有继承的例子:
class BaseClass {
public:
int public_member;
protected:
int protected_member;
private:
int private_member;
};
class DerivedClass : private BaseClass {
public:
void ExampleFunction() {
int x = public_member; // 正确
int y = protected_member; // 正确
int z = private_member; // 编译错误
}
};
在这个例子中, DerivedClass 以 private 的方式继承 BaseClass,因此派生类的所有成员函数都可以访问基类的成员,但是外部程序不能访问派生类的任何基类的成员。这通常用于实现“has-a”(有一)关系,其中一个类将另一个类作为其成员对象来使用。
1.3 保护继承
保护继承是以 protected 的方式继承基类的,这意味着派生类可以访问基类中的 protected 成员,但不能访问基类中的 public 成员和 private 成员。下面是一个保护继承的例子:
class BaseClass {
public:
int public_member;
protected:
int protected_member;
private:
int private_member;
};
class DerivedClass : protected BaseClass {
public:
void ExampleFunction() {
int x = public_member; // 编译错误
int y = protected_member; // 正确
int z = private_member; // 编译错误
}
};
在这个例子中, DerivedClass 以 protected 的方式继承 BaseClass,因此派生类的所有成员函数都可以访问基类的 protected 成员,但是不能访问 public 和 private 成员。
2. 继承方式与访问限定符的关系
继承方式和访问限定符之间有很强的关联,从而决定了派生类对于基类成员的访问状态。接下来分别介绍派生类对于基类成员访问的不同情况。
2.1 共有继承
在公有继承中,派生类可以访问基类中的公有成员和受保护成员。但是,私有成员在继承时会变成派生类中的一部分,而不能被派生类中的任何成员访问。下面是一个公有继承的例子:
class BaseClass {
public:
int public_member;
protected:
int protected_member;
private:
int private_member;
};
class DerivedClass : public BaseClass {
public:
void ExampleFunction() {
int x = public_member; // 可以访问
int y = protected_member; // 可以访问
int z = private_member; // 编译错误
}
};
在这个例子中, public_member 和 protected_member 可以被 ExampleFunction() 成员函数访问,而 private_member 不能被访问。
2.2 私有继承
在私有继承中,基类中的成员都变成了派生类的私有成员。因此,被继承的成员只能被派生类的成员函数访问,而不能被外部程序或派生类的子类访问。下面是一个私有继承的例子:
class BaseClass {
public:
int public_member;
protected:
int protected_member;
private:
int private_member;
};
class DerivedClass : private BaseClass {
public:
void ExampleFunction() {
int x = public_member; // 编译错误
int y = protected_member; // 可以访问
int z = private_member; // 编译错误
}
};
在这个例子中, public_member 和 private_member 不能被 ExampleFunction() 成员函数访问,而 protected_member 可以被访问。
2.3 保护继承
在保护继承中,基类中的受保护成员和公有成员都变成了派生类的受保护成员。因此,被继承的成员只能被当前类的对象或其子类对象访问,而不能被外部程序访问。下面是一个保护继承的例子:
class BaseClass {
public:
int public_member;
protected:
int protected_member;
private:
int private_member;
};
class DerivedClass : protected BaseClass {
public:
void ExampleFunction() {
int x = public_member; // 编译错误
int y = protected_member; // 可以访问
int z = private_member; // 编译错误
}
};
class SubClass : public DerivedClass {
public:
void ExampleFunction2() {
int x = public_member; // 编译错误
int y = protected_member; // 可以访问
int z = private_member; // 编译错误
}
};
在这个例子中, public_member 和 private_member 都不能被 ExampleFunction() 成员函数和 ExampleFunction2() 成员函数访问,而 protected_member 可以被派生类和其子类的成员函数访问。
总结
继承方式和访问限定符是C++中非常重要的概念,通过掌握这些概念,可以实现代码的复用和封装。对于从基类派生出的子类,访问限定符限制了其对于基类成员的访问,从而保证分类的数据和行为不被篡改和误用。因此,在进行C++面向对象编程时,一定要熟练掌握这种方式以及其访问控制规则,并灵活使用,从而实现代码的高效度和安全性。