我正在使用void*在某些功能中接受的 API 。我经常不小心将错误的指针类型传递给函数,当然它编译得很好,但在运行时不起作用。
有没有办法禁用void*指向某个类的指针的隐式转换?
下面代码中的静态断言失败。
当然,我知道这是因为 Bar 中用户提供的移动构造函数。
#include <type_traits>
using namespace std;
struct Bar
{
public:
Bar() = default;
Bar(const Bar&) = default;
~Bar() = default;
Bar(Bar&&)
{
}
};
struct Foo
{
Bar b;
Foo() = default;
~Foo() = default;
Foo(const Foo&) = default;
Foo(Foo&&) = delete;
Foo & operator= (Foo && ) = delete;
Foo & operator= (const Foo & ) = delete;
};
static_assert(is_trivially_copyable_v<Foo>); // Fails
Run Code Online (Sandbox Code Playgroud)
我不明白的是如何解释关于平凡可复制性的标准。来自 C++ 17 标准:
一个简单可复制的类是一个类:
(6.1) 其中每个复制构造函数、移动构造函数、复制赋值运算符和移动赋值运算符 ([class.copy], [over.ass]) 被删除或微不足道,
(6.2) 至少有一个未删除的复制构造函数、移动构造函数、复制赋值运算符或移动赋值运算符,并且
(6.3) 有一个简单的、未删除的析构函数。 …
如果一个类有很多私有函数,在头文件中声明它们似乎是不可取的。它使客户端更难解析类的接口并增加编译时间。
当然,一种选择是 pimpl 惯用法,但这会增加一层间接性并导致内存分配。
下面是在实现文件中定义的友元类中隐藏辅助函数的示例。
这个成语有名字吗?
有什么理由不这样做吗?
//Foo.h
class Foo
{
public:
void FuncA();
void FuncB();
private:
int x;
// more data...
friend struct FooHelpers;
};
Run Code Online (Sandbox Code Playgroud)
//Foo.cpp
struct FooHelpers
{
static void Helper1(Foo& f)
{
// manipulate private data..
f.x++; //etc.
}
// Possibly more funcs...
};
void Foo::FuncA()
{
//....
FooHelpers::Helper1(*this);
//....
}
//....
Run Code Online (Sandbox Code Playgroud)