gpt4 book ai didi

c++ - 非成员非 friend 函数与私有(private)函数

转载 作者:IT老高 更新时间:2023-10-28 22:34:02 25 4
gpt4 key购买 nike

Herb Sutter 说过,在 C++ 中编写方法最面向对象的方式是使用非成员非友元函数。这是否意味着我应该采用私有(private)方法并将它们转换为非成员非 friend 函数?这些方法可能需要的任何成员变量都可以作为参数传入。

示例(之前):

class Number {
public:
Number( int nNumber ) : m_nNumber( nNumber ) {}
int CalculateDifference( int nNumber ) { return minus( nNumber ); }
private:
int minus( int nNumber ) { return m_nNumber - nNumber; }
int m_nNumber;
};

示例(之后):

int minus( int nLhsNumber, int nRhsNumber ) { return nLhsNumber - nRhsNumber; }
class Number {
public:
Number( int nNumber ) : m_nNumber( nNumber ) {}
int CalculateDifference( int nNumber ) { return minus( m_nNumber, nNumber ); }
private:
int m_nNumber;
};

我在正确的轨道上吗?是否应该将所有私有(private)方法移至非成员非 friend 函数?应该有哪些规则可以告诉您其他情况?

最佳答案

我相信自由函数并且同意 Sutter 的观点,但我的理解是相反的。这并不是说您应该让您的公共(public)方法依赖于自由函数而不是私有(private)方法,而是您可以通过使用提供的公共(public)接口(interface)在具有自由函数的类之外构建更丰富的接口(interface)。

也就是说,您不会将您的私有(private)信息推送到类之外,而是将公共(public)接口(interface)减少到最低限度,从而允许您以尽可能少的耦合构建其余功能:仅使用公共(public)接口(interface)。

在您的示例中,如果可以根据其他操作有效地表示,我将移到类之外的是 CalculateDifference 方法。

class Number { // small simple interface: accessor to constant data, constructor
public:
explicit Number( int nNumber ) : m_nNumber( nNumber ) {}
int value() const { return m_nNumber; }
private:
int m_nNumber;
};
Number operator+( Number const & lhs, Number const & rhs ) // Add addition to the interface
{
return Number( lhs.value() + rhs.value() );
}
Number operator-( Number const & lhs, Number const & rhs ) // Add subtraction to the interface
{
return Number( lhs.value() - rhs.value() );
}

优势在于,如果您决定重新定义 Number 内部结构(对于这样一个简单的类,您无能为力),只要您保持公共(public)接口(interface)不变,那么所有其他功能都可以正常工作盒子。内部实现细节不会强制您重新定义所有其他方法。

困难的部分(不在上面的简单示例中)是确定您必须提供的最少接口(interface)是什么。文章 (GotW#84) 是一个很好的例子,引用自上一个问题。如果您仔细阅读它,您会发现可以大大减少 std::basic_string 中的方法数量,同时保持相同的功能和性能。数量将从 103 个成员函数减少到只有 32 个成员。这意味着类中的实现更改将仅影响 32 个成员而不是 103 个成员,并且由于保留了接口(interface),因此可以实现 32 个成员的其余功能的 71 个自由函数将不必更改。

这是重要的一点:它更加封装,因为您限制了实现更改对代码的影响。

离开原来的问题,这里有一个简单的例子,说明使用自由函数如何提高类更改的局部性。假设一个具有非常复杂的加法运算的复杂类。你可以去实现它并将所有运算符覆盖实现为成员函数,或者你可以轻松有效地在内部只实现其中的一些,并将其余的作为自由函数提供:

class ReallyComplex
{
public:
ReallyComplex& operator+=( ReallyComplex const & rhs );
};
ReallyComplex operator+( ReallyComplex const & lhs, ReallyComplex const & rhs )
{
ReallyComplex tmp( lhs );
tmp += rhs;
return tmp;
}

不难看出,无论原来的operator+=如何执行任务,免费的operator+都能正确执行任务。现在,随着对类的任何和所有更改,operator+= 将不得不更新,但外部 operator+ 将在其余生中保持不变。

上面的代码是一个常见的模式,虽然通常不是通过常量引用接收lhs操作数并在里面创建一个临时对象,而是可以改变它,使参数本身是一个值拷贝,帮助编译器进行一些优化:

ReallyComplex operator+( ReallyComplex lhs, ReallyComplex const & rhs )
{
lhs += rhs;
return lhs;
}

关于c++ - 非成员非 friend 函数与私有(private)函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1055576/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com