[英]Do I need to define all private functions and variables in class header C++
In a C++ class, should I be placing my private functions and variables in the private section of the class header definition, or in the class source file and why? 在C ++类中,我应该将我的私有函数和变量放在类头定义的私有部分中,还是放在类源文件中,为什么?
For example: 例如:
// Header
class MyClass {
public:
void doSomething();
private:
int a = 0;
}
// Source
void MyClass::doSomething()
{
// Do something with `a`
}
or 要么
// Header
class MyClass {
public:
void doSomething();
}
// Source
int a = 0;
void MyClass::doSomething()
{
// Do something with `a`
}
I've always thought, when programming it's best to make the scope of a function/variable as small as possible. 我一直认为,编程时最好尽量减小函数/变量的范围。 So shouldn't restricting the scope of the var
a
to the scope of the source file be best? 那么不应该将var
a
的范围限制在源文件的范围内最好吗?
They are not equivalent. 他们并不等同。 First example
第一个例子
// 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()
}
Output 产量
1
1
Second example 第二个例子
// 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()
}
Output 产量
1
2
In the first example a
is a class variable so x
and y
have their own copy of a
. 在第一个例子中,
a
是一个类变量,因此x
和y
有自己的a
副本。 In the second example there is only one global variable a
so the output is different. 在第二个示例中,只有一个全局变量
a
因此输出不同。
You could use the pimpl idiom... Alternatively, you could use this variant of the pimpl idiom, where the memory of the implementation is directly provided by the interface class: 您可以使用pimpl习惯用法......或者,您可以使用pimpl习惯用法的这种变体,其中实现的内存由接口类直接提供:
In file MyClass.hpp
: 在文件
MyClass.hpp
:
class MyClass{
private:
std::byte buffer[N];
public:
MyClass();
void public_method();
~MyClass();
};
In class MyClass.cpp
: 在类
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();
/*....*/
}
Compared to classical pimpl idiom: 与传统的pimpl成语相比:
Pros : less memory access, no memory allocation on the heap, more efficient 优点 :更少的内存访问,堆上没有内存分配,更高效
Cons : error prone, the size of the implementation "leak" in the interface. 缺点 :容易出错,接口中执行“泄漏”的大小。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.