隐藏继承的函数
更改继承成员的访问级别
C ++使我们能够在派生类中更改继承成员的访问说明符。这是通过使用using声明来标识在新的访问说明符下,在派生类中,更改其访问权限的(作用域)基类成员来完成的。
例如,考虑以下Base:
#include <iostream>
class Base
{
private:
int m_value;
public:
Base(int value)
: m_value(value)
{
}
protected:
void printValue() { std::cout << m_value; }
};
因为Base :: printValue()已声明为protected,所以它只能由Base或其派生类调用。公众无法访问它。
让我们定义一个Derived类,它将printValue()的访问说明符更改为public:
class Derived: public Base
{
public:
Derived(int value)
: Base(value)
{
}
// Base :: printValue作为受保护继承,因此公共没有访问权限
// 但我们通过使用声明将其更改为公开
using Base::printValue; // 注意:这里没有括号
};
这意味着此代码现在可以正常工作:
int main()
{
Derived derived(7);
// printValue在Derived中是公共的,所以这没关系
derived.printValue(); // 打印7
return
0;
}
两个说明:
首先,您只能更改派生类通常能够访问的基本成员的访问说明符。因此,您永远不能将基本成员的访问说明符从private更改为protected或public,因为派生类无权访问基类的私有成员。
其次,从C ++ 11开始,using声明是更改访问级别的首选方式。但是,您也可以使用“访问声明”更改访问级别。这与使用声明方法的工作方式相同,但省略了“using”关键字。这种重新定义访问权限的访问声明方式现在被认为已弃用,但您可能会看到使用此模式的旧代码,因此值得了解。
隐藏函数
在C ++中,除了修改源代码之外,不可能从基类中删除或限制功能。但是,在派生类中,可以隐藏基类中存在的函数,以便无法通过派生类访问它。这可以通过更改相关的访问说明符来完成。
例如,我们可以将公共成员设为私有:
#include <iostream>
class Base
{
public:
int m_value;
};
class Derived : public Base
{
private:
using Base::m_value;
public:
Derived(int value)
// 我们无法初始化m_value,因为它是Base成员(Base必须初始化它)
{
// 但我们可以为它分配一个值
m_value = value;
}
};
int main()
{
Derived derived(7);
// 以下操作无效,因为m_value已重新定义为私有
std::cout << derived.m_value;
return 0;
}
请注意,这允许我们采用设计不良的基类并将其数据封装在派生类中。或者,不是公开继承Base的成员并通过覆盖其访问说明符使m_value私有,我们可以私有地继承Base,这将导致所有Base的成员首先私有继承。
您还可以在派生类中将成员函数标记为已delete,这可确保它们无法通过派生对象进行调用:
#include <iostream>
class Base
{
private:
int m_value;
public:
Base(int value)
: m_value(value)
{
}
int getValue() { return m_value; }
};
class Derived : public Base
{
public:
Derived(int value)
: Base(value)
{
}
int getValue() = delete; // 将此函数标记为无法访问
};
int main()
{
Derived derived(7);
// 以下内容无效,因为getValue()已被删除!
std::cout << derived.getValue();
return 0;
}
在上面的例子中,我们将getValue()函数标记为已delete。这意味着当我们尝试调用函数的派生版本时,编译器会报错。请注意,仍然可以访问getValue()的Base版本。