处理非const知识库/ SDK的最佳方法是什么?

时间:2018-02-17 10:21:15

标签: c++ const 3dsmax

我现在使用3ds max SDK工作的时间更长,几乎所有部分都没有使用const。因此即使Width()的{​​{1}}或Height()获取者也未被标记为Bitmap。这在小型项目中已经是一个真正的烦恼,但由于我一直在研究一个更大的项目,它变得越来越可怕。

例如,出于性能原因,我在多个类实例中持有单个const实例作为Bitmap成员。当然,有些情况我想通过一切实例来避免单个实例更改所有实例的属性,因此所有原始指针获取器(SDK所必需的)都会传递shared_ptr<Bitmap>。不幸的是,现在我甚至无法询问const Bitmap*的宽度 - 因为const Bitmap*是非常量的。

我问自己,解决这个问题的最佳方法是什么。我看到三个选项:

  • 完全忘掉const,让一切都变成非常。在我曾经做过的较小的项目中,但就像我说的那样,使用更复杂的技术,它变得更加危险。
  • 在每个必要的地方建立一个就地Width()。那将是很多地方,阅读起来非常糟糕。
  • 为3ds max类编写包装器,它至少为可能非常安全的方法提供const_cast方法。这会将所有const封装在一个地方,也适用于其他项目。

我被警告(我知道)这可能是基于意见的。但是我现在很长时间不得不处理这个恼人的问题,我真的很想找到一个解决方案,因此需要其他人的经验。

2 个答案:

答案 0 :(得分:3)

首先,我想提一下,const正确性的缺失可能因实现细节而合理,例如getter函数可能会对内部同步原语执行锁定,因此总是会改变内部状态而无法标记作为const

int Bitmap::Width(void)
{
     int width{};
     ::std::lock_guard<::std::mutex> const lock{m_sync};
     width = m_width;
     return width;
}

作为一种解决方法,您可以编写专用的PImpl位图包装器,限制使用适当的const限定符直接访问感兴趣的位图实现转发函数:

class SharedBitmap
{
    private: ::std::shared_ptr<Bitmap> m_p_bitmap;

    public: int Width(void) const
    {
        return m_p_bitmap->Width();
    }

    // other methods...
};

请注意,此方法与有问题的第三个选项不同,因为它不涉及const_cast

答案 1 :(得分:1)

根据我的经验(10年代),“const”一直是一个比它更有帮助的更大的因素。不要提到代码越来越长,因此难以阅读。如果您想知道库是如何工作的,那么无论如何都要阅读手册,而不是标题。如果您想知道自己做得对,那就进行功能测试。地狱甚至有静态分析工具检查变量是否被写入,而没有使用无用的非功能元数据来加载代码以捕获未记录的使用模式。而且由于有很多方法可以破坏const,因此它是捕获此类错误的正确方法。

总之,在我看来,选项1是最有效的解决方案。 (这是一种观点吗?那些不同意的人可能会这么认为。)

对于const的快速清除后,您可以#define const甚至-Dconst删除它,但是否安全可能取决于您的具体情况illegal use正在为标准标头执行此操作。我做了类似#define private|protected public的类似黑客,而不是在做白盒测试时弄乱friend,就像魅力一样!

知道“常量变量”的概念在许多编程语言中都是无效的,如果没有它,它们似乎就可以了。

你需要const的唯一时间是C字符串常量/字符串文字。但是,似乎不是你的情况。

相关问题