C ++:为什么必须私有函数声明?(C++: Why must private functions

2019-07-30 11:32发布

为什么用C ++的类必须申报其私人的功能呢? 有它实际的技术原因(什么是它在编译时的作用),或者是它只是出于一致性的缘故?

Answer 1:

我问为什么私有函数必须在所有声明,因为它们不增加对其他翻译单元知道的任何事情(无论物体的大小,也不V表项)

如果你想想看,这是类似声明某些功能static的文件。 它不是从外部看到,但它是编译器本身是重要的。 编译器想知道该函数的签名,才可以使用它。 这就是为什么你在第一时间申报功能。 请记住,C ++编译器是一个通,这意味着一切具有在使用前被声明。 1

但从程序员的角度,宣告私人功能还没有完全没用。 想象一下,2班,其中一个是friend的其他的。 该friendzoned 2级需要知道这样的类看的士兵一样,(这个讨论越来越怪异),否则不能使用它。

至于到底为什么C ++的设计以这种方式,我想先说有历史原因:事实上,你不能切在C结构,通过了C ++,所以你不能切类(或通过的其它语言从C ++支链的,也是如此)。 我还猜想,它是关于简单:想象一下,这将是多么困难,设计编制的方法中,你可以分割不同的头文件中的类,让你的源文件了解它,并防止其他人添加的东西到您的类。

最后需要说明的是, private函数可以影响虚函数表的大小。 也就是说,如果它们是virtual


1 其实不完全是。 如果你在课堂上有内联函数,可以参考后在同一类中定义的功能。 不过,也许想法从单通道开始,这个异常后添加进去。

2 这是特别内联成员函数。



Answer 2:

你必须所有成员申报,这样编译器知道哪些功能是允许为成员的类本身的定义。 否则,第二程序员可以(不小心?)出现并添加成员,犯错误,并侵犯了您的对象的担保,从而导致未定义的行为和/或随机崩溃。



Answer 3:

有关注的组合,但是:

  • C ++不会让你重新打开一个类的初始定义后,在其新成员申报。
  • C ++不会让你有结合形成一个程序的不同转换单元的一类不同的定义。

因此:

  • 该.cpp文件类中声明需要的任何私有成员函数需要在.h文件中,该班的每个用户看到太多被定义。

从实际的二进制兼容性的POV:大卫在注释中说,私人virtual功能影响的大小和这个类的虚函数表的布局和使用它作为一个基础的任何类。 所以编译器需要知道它们编译代码不能叫他们时也是如此。

难道C ++已经发明不同,允许.cpp文件重新打开类并添加额外的成员函数某些种类的,具有所要求的落实安排,这不会打破二进制兼容性? 可以在一个定义规则放宽,允许在某些方面有所不同的定义? 例如,静态成员函数和非虚拟非静态成员函数。

也许是这两个。 我不认为有任何技术障碍,虽然目前ODR是非常严格的关于是什么导致定义“不同”(因此在允许非常相似的外观定义之间的二进制不兼容性非常大方地实现)。 我认为,引进这种异常的规则文本将是复杂的。

最终它可能会回落到“的设计者希望它这样”,或者它可能是有人尝试过了,遇到我都没有想到的障碍。



Answer 4:

访问级别不影响能见度。 私人功能是外部可见的代码,并且可以通过重载解析(然后这将导致一个存取错误violoation)来选择:

class A {
    void F(int i) {}
public:
    void F(unsigned i) {}
};

int main() {
    A a;
    a.F(1); // error, void A::F(int) is private
}

试想一下,当混乱这个作品:

class A {
public:
    void F(unsigned i) {}
};

int main() {
    A a;
    a.F(1);
}

// add private F overload to A
void A::F(int i) {}

但它改变为第一代码导致重载来选择不同的功能。 约在下面的例子是什么?

class A {
public:
    void F(unsigned i) {}
};

// add private F overload to A
void A::F(int i) {}

int main() {
    A a;
    a.F(1);
}

或者,这里是这个脚麻的另一个例子:

// A.h
class A {
public:
    void g() { f(1); }
    void f(unsigned);
};

// A_private_interface.h
class A;
void A::f(int);

// A.cpp
#include "A_private_interface.h"
#include "A.h"

void A::f(int) {}
void A::f(unsigned) {}

// main.cpp
#include "A.h"

int main() {
    A().g();
}


Answer 5:

原因之一是,在C ++的朋友可以访问您的私处。 对于朋友来访问它们,朋友们一定要了解他们。



Answer 6:

一类的私有成员仍然是类的成员,因此,它们必须申报,其他公共成员的实现可能依赖于私有方法。 声明他们将让编译器知道该函数作为一个成员函数调用的调用。

如果您有只使用INT的一个方法.cpp文件,不依赖于直接访问类的其他私有成员,考虑将其移动到一个匿名的命名空间。 然后,它并不需要在头文件中声明。



Answer 7:

还有为什么私有函数必须声明几个原因。

首先编译时错误检查

访问修饰符点是在编译时捕捉编程错误某些类别(没有双关语意)。 私有函数都是函数,如果有人从外面类叫他们,那将是一个错误,并希望尽早知道。

第二次浇铸和继承

从C ++标准采取:

3 [注:私有基类的成员可能无法访问作为继承成员的名字,而是直接访问。 因为指针转换规则(4.10)和显式转换(5.4)的,可能会形成不良的从一个指针到一个派生类的指针不可访问的基类的变换,如果使用的隐式转换的,但结构良好的如果使用显式类型转换。

第三个朋友

朋友显示对方有士兵。 私有方法可以被另一个类,它是一个朋友被调用。

第四一般理智和良好的设计

在一个项目上工作过与其他100个开发者。 有一个标准和一般的一套规则有助于保持维护。 声明私人的东西有特定的含义,每个人都在一组。

另外这款流入良好的面向对象设计原则。 什么揭露,什么不可以



文章来源: C++: Why must private functions be declared?