You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C++14中如何阻止sizeof运算符作用于完整类型并触发编译错误

可行方案

因为sizeof是C内置运算符,不支持重载,所以你最初尝试的运算符删除写法是不生效的,目前有两类符合C14标准的方案可以实现需求,分别适用于不同的场景:


方案1:Pimpl惯用法(无hack,可靠性最高)

如果你可以接受自定义类型对外只暴露不完整声明,用Pimpl(指针指向实现)的方式封装,就可以从语法层面完全阻止外部代码对实现类使用sizeof:

// 对外暴露的头文件 my_class.h
class MyClass {
public:
    MyClass();
    ~MyClass();
    // 对外暴露的所有接口声明
    void do_something();
    int get_value() const;
private:
    struct Impl; // 仅前置声明,无完整定义
    Impl* impl_;
};
// 内部实现文件 my_class.cpp
#include "my_class.h"

// 实现类的完整定义仅在cpp内可见,外部完全无法访问
struct MyClass::Impl {
    int data = 0;
    // 其他内部成员、方法
};

// 所有对外接口的实现都转发到内部impl
MyClass::MyClass() : impl_(new Impl()) {}
MyClass::~MyClass() { delete impl_; }
void MyClass::do_something() { impl_->data++; }
int MyClass::get_value() const { return impl_->data; }

这个方案的特性:

  • 完全符合C++标准,无任何hack,全编译器兼容
  • 外部代码只能看到MyClass::Impl的前置声明,属于不完整类型,任何对MyClass::Impl使用sizeof的代码都会直接触发编译错误
  • 如果连对外的MyClass本身的sizeof也要禁止,可以进一步只对外暴露MyClass的前置声明,只返回指针/引用类型的访问接口:
    // 头文件中仅保留声明,无类定义
    #include <memory>
    class MyClass;
    std::unique_ptr<MyClass> create_my_class();
    void my_class_do_something(MyClass* obj);
    

方案2:宏替换hack(类完整定义可见的场景下生效)

如果你必须让自定义类的完整定义对外可见,可以用宏替换sizeof做编译期检查,只要在你要生效的代码作用域内定义如下宏即可:

#include <type_traits>

// 你的自定义类
class ForbidSizeofClass {
public:
    int a;
    void func() {}
    // 其他类成员定义
};

// 放在头文件末尾,必须在所有系统、标准库头文件引入之后定义
#define sizeof(...)                                                                 \
    static_assert(                                                                  \
        !std::is_same<typename std::decay<decltype(__VA_ARGS__)>::type, ForbidSizeofClass>::value, \
        "sizeof is forbidden on ForbidSizeofClass"                                  \
    );                                                                              \
    sizeof(__VA_ARGS__)

这个方案的限制:

  • 必须在包含所有系统、标准库头文件之后定义该宏,否则会破坏标准库内部的sizeof使用
  • 宏仅在定义之后的代码中生效,未包含这个宏定义的翻译单元不受影响
  • 可以通过写::sizeof的方式绕过检查,但常规编码场景下几乎不会出现这种写法
  • 如果要支持禁止多个类型的sizeof,在静态断言的判断条件中扩展即可。

内容的提问来源于stack exchange,提问作者CoffeeTableEspresso

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.05 18:27:03