代码之家  ›  专栏  ›  技术社区  ›  Tien Do

使用遗留代码(使用reinterpret\u cast)真的是一种好技术吗?

c++
  •  0
  • Tien Do  · 技术社区  · 7 年前

    下面的代码来自一篇关于C++面试问题的帖子 here . 我从来都不知道这个技巧(尽管有人说它很好)。我的问题是:在什么情况下我们需要使用它?您经常在实际的生产/遗留代码中看到它吗?

    问题:

    实现一个方法来获取任何给定Something*对象的topSecretValue。方法应该是跨平台兼容的,并且不依赖于sizeof(int,bool,string)。

    class Something {
        Something() {
            topSecretValue = 42;
        }
        bool somePublicBool;
        int somePublicInt;
        std::string somePublicString;
    private:
        int topSecretValue;
    };
    

    回答:

    创建另一个类,该类的所有成员顺序相同,但有额外的公共方法返回值。您的副本类应该如下所示:

    class SomethingReplica {
    public:
        int getTopSecretValue() { return topSecretValue; } // <-- new member function
        bool somePublicBool;
        int somePublicInt;
        std::string somePublicString;
    private:
        int topSecretValue;
    };
    
    int main(int argc, const char * argv[]) {
        Something a;
        SomethingReplica* b = reinterpret_cast<SomethingReplica*>(&a);
        std::cout << b->getTopSecretValue();
    }
    

    在最终产品中避免这样的代码是很重要的,但在处理遗留代码时,这是一种很好的技术,因为它可以用于从库类中提取中间计算值。(注意:如果发现外部库的对齐方式与代码不匹配,可以使用#pragma pack解决此问题。)

    0 回复  |  直到 7 年前
        1
  •  7
  •   Remy Lebeau    7 年前

    你可以不用 reinterpret_cast . 下面的博客文章介绍了一个使用模板和朋友的技巧,演示了这项技术:

    Access to private members. That's easy!

    这当然比面试官的方法更安全,因为它消除了重新创建类定义时的人为错误。不过,这种方法到底好吗?给定的问题有一些难以置信的人为约束,很少适用于“真实”的项目。如果是C++项目,并且你可以访问头文件,为什么不添加一个吸气剂?如果不是C++项目,为什么你对互操作类的定义如此受限?