我需要在类C 中定义所有私人功能和变量
Do I need to define all private functions and variables in class header C++
在C 类中,我是否应该将我的私人功能和变量放在类标题定义的私有部分或类源文件中,为什么?
例如:
// Header
class MyClass {
public:
void doSomething();
private:
int a = 0;
}
// Source
void MyClass::doSomething()
{
// Do something with `a`
}
或
// Header
class MyClass {
public:
void doSomething();
}
// Source
int a = 0;
void MyClass::doSomething()
{
// Do something with `a`
}
我一直认为,在编程时,最好使函数/变量的范围尽可能小。因此,不应该将var a
的范围限制为源文件范围吗?
它们不是等效的。第一个示例
// Header
class MyClass {
public:
void doSomething();
private:
int a = 0;
}
// Source
void MyClass::doSomething()
{
++a;
cout << a << endl;
}
int main()
{
MyClass x, y;
x.doSomething();
y.doSomething()
}
输出
1
1
第二个示例
// Header
class MyClass {
public:
void doSomething();
}
int a = 0;
// Source
void MyClass::doSomething()
{
++a;
cout << a << endl;
}
int main()
{
MyClass x, y;
x.doSomething();
y.doSomething()
}
输出
1
2
在第一个示例中,a
是类变量,因此x
和y
具有自己的a
副本。在第二个示例中,只有一个全局变量a
,因此输出不同。
您可以使用pimpl成语...或者,您可以使用PIMPL成语的此变体,其中实现的内存由接口类直接提供:
在文件MyClass.hpp
中:
class MyClass{
private:
std::byte buffer[N];
public:
MyClass();
void public_method();
~MyClass();
};
在类MyClass.cpp
中:
#include "MyClass.hpp"
namespace{
struct MyClassImpl{
private:
int val=0;
public:
void secret_method(){/*...*/}
};
inline const MyClassImpl&
get(const std::byte* buffer){
//In theory, in C++17 you should use std::launder here to be standard compliant
//in practice, compilers generate the expected code without std::launder
//and with std::launder they generate horrible and inefficient code!
return *reinterpret_cast<const MyClassImpl*>(buffer);
}
inline MyClassImpl&
get(const std::byte* buffer){
//idem here to be c++17 standard compliant launder is necessary
//in practice, it would be a mistake.
return *reinterpret_cast<MyClassImpl*>(buffer);
}
}
MyClass::MyClass(){
new(buffer) MyClassImpl{};
}
MyClass::~MyClass(){
get(buffer).~MyClassImpl();
}
void
MyClass::public_method(){
/*....*/
get(buffer).secret_method();
/*....*/
}
与经典的pimpl成语相比:
pros :更少的内存访问,没有内存分配,更有效
cons> cons :易犯错,界面中实现"泄漏"的大小。
相关文章:
- 将 2D 数组传递给大小为变量的功能
- 将非静态成员函数C 的使用无效,而将成员功能作为函数变量
- 功能原型变量范围C
- 避免为每个成员变量重复功能
- 线程安全性和静态变量/成员功能
- 功能和变量从何而来
- 无全局变量或功能参数的递归调用
- 在已经运行的功能C 中更改变量
- 将功能输出分配给变量
- 从成员变量更新类变量或调用类功能是给出运行时错误
- 如何访问C 中的功能范围变量
- 我的朋友功能无法访问私人变量
- 不同的变量和功能起作用
- 在功能中设置对象变量
- 类和本地功能变量内的全局变量
- 我需要在类C 中定义所有私人功能和变量
- 如何在Arduino的功能中提供软件变量
- 是否可以在C++中推迟 const 变量的初始化,例如 Java 的"blank final"功能?
- 无法从类中的其他功能访问同一类的变量
- 操纵功能变量在doxygen中