C++基础教程面向对象(学习笔记(50))

隐藏继承的函数

更改继承成员的访问级别

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版本。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值