在C++中使用类的私有方法是否是一种可接受的方式?

Is it an acceptable way to use class' private methods in C++?

本文关键字:一种 方式 可接受 有方法 C++ 是否是      更新时间:2024-09-21

在我的C++程序中,我有一个类,在某些方法中发生了相同的例程,例如打开流以读取/写入文件,解析文件,确定MIME类型等。为了使方法更紧凑并避免多次键入相同的代码,我将这些常规操作拆分为私有方法,仅在类内部使用。但是,其中一些私有方法依赖于其他方法的结果,因此以错误的顺序调用这些方法可能会导致非常糟糕的后果。 只是一个愚蠢的例子:

class Example
{
public:
Example(int x);
~Example() {}
//...
//...
protected:
private:
int a;
int b;
bool c;
void foo_();
void bar_();
//...
//...
};
Example::Example(int x) : a(x)
{
foo_();
bar_();
}
void Example::foo_()
{
if (a == 0)
{
b = 10;
}
else
{
b = a * 2;
}
}
void Example::bar_()
{
if (b == 0)
{
c = false;
}
else
{
c = true;
}
}

从上面的示例中可以看出,在构造函数中foo_()之前调用bar_()将导致未定义的行为,因为尚未初始化b。但是,如果我绝对确定我在类内正确使用这些私有方法,并且它们永远不能在类外使用,那么我是否应该为这些细微差别而烦恼?

更不用说你所做的推荐的方式!每当函数内有多个不同的操作时,标准方法是将函数分成多个函数。在您的情况下,用户不需要这些功能,因此将它们设为私有是你能做的最好的事情!当涉及到"我需要按特定顺序调用它们"的部分时,如果代码需要按特定顺序调用,则完全没问题。我的意思是,在bar之后调用foo的唯一逻辑是前者取决于后者的结果。这与在将内存用作数组之前需要为int* p分配内存时没有太大区别。虽然,正如@Basil和许多其他人所解释的那样,请务必正确记录您的代码

构造函数中foo_()之前调用bar_()将导致未定义的行为,因为b尚未初始化

根据经验,我总是显式初始化构造函数中的所有成员字段(特别是那些具有标量类型的字段,如指针或数字,例如class Example内部的abc)。优点:程序的行为更具可重现性。缺点:编译的代码可能会运行无用的初始化(但聪明的优化编译器会删除它们)。

如果使用 GCC 编译,请将其用作g++ -Wall -Wextra -g。它通常会给你有用的警告。

对于大型C++项目,请考虑记录您的编码规则(在单独的书面文档中,在纸上分发给您团队中的所有开发人员),并使用您的 GCC 插件检查其中的一些规则。另请参阅DECODER项目和Bismon静态源代码分析器,以及Clang静态分析器(所有GCC,Bismon和Clang分析器都是开源的,您可以改进其源代码)。

在某些情况下,会生成一些C++代码。参见GNU bison,ANTLR,RefPerSys,FLTK,Qt作为生成C++代码或提供发出C++代码的代码生成器的软件项目的示例。在 x86/64 PC 上,你可以在运行时使用 ASMJIT 或 libgccjit 生成机器代码,并通过函数指针调用该代码(在 Linux 上另请参阅 dlopen(3)、dlsym(3) 和 C++ dlopen minihowto...)。如果您的软件项目具有C++代码生成器(例如使用 GPP),则可以确保生成的代码遵循某些编码约定和不变量。但是要注意赖斯定理。

如果使用 GDB 进行调试,请阅读其watch命令和观察点。

我也知道C++五法则。