我试图在我的项目中实现C++库的使用,该库未在其访问函数上使用const修饰符.到目前为止,我一直在我的所有代码中使用const,但是这个新库导致了两个主要问题:
如果这些参数是由库定义的类型,则作为const引用传递参数的函数不能使用参数的访问函数.
具有库定义的类型的成员对象的类不能在const函数中使用这些对象的访问函数.
克服这个问题的最佳方法是什么?最简单的解决方案是简单地从我的代码中删除所有const的使用,但这样做会非常令人沮丧.
附加信息:在这种情况下,我可以访问源代码,并且可以看到访问函数不会修改任何内容.我省略了这些信息,因为我对更一般的情况感兴趣.对于我的情况,const_cast
似乎是要走的路
PS图书馆作家并不邪恶!这是一个粗略和准备好的代码,他善于开源.我可以放弃图书馆并使用其他人注意到的更专业的东西.但是,对于这个时间有限的小项目,该库接口的简单性使其成为最佳选择.
判断库中的函数是否实际修改了什么是多么容易?
如果它很容易分辨,而它们没有,那么你可以使用const_cast
const指针/引用非const并调用库函数.您可能希望在库类周围添加一个包装器来为您执行此操作,这是繁琐且冗长的,但是从您的类中获取该代码.这个包装器可能是一个子类,它添加了一些const访问器,这取决于你使用库类的方式是否允许它工作.
如果很难说,或者他们确实修改了东西,那么你需要在代码中使用非const实例和对库类的引用.mutable
可以帮助那些类型(2),但对于类型(1)的那些你只需要传递非const参数.
有关它可能很难的原因的一个例子,请考虑库作者可能写了这样的东西:
struct Foo {
size_t times_accessed;
int value;
int get() {
++times_accessed;
return value;
}
};
Run Code Online (Sandbox Code Playgroud)
现在,如果你const_cast
是一个和调用的const
实例,你有未定义的行为[*].所以你必须确保它真的不会修改它所调用的对象.您可以通过确保永远不会创建任何const实例来缓解这一点,即使您确实对非const实例进行了const引用.这样,当你和你打电话至少不会造成UB.它可能会使您的代码混乱,字段会不断更改您的函数声称不会修改的对象.Foo
get()
get
Foo
const_cast
get
[*]为什么它是未定义的行为?它必须是,语言可以保证const
对象的值永远不会在有效程序中更改.这种保证允许编译器做有用的事情.例如,它可以将static const
对象放在只读数据部分中,并且可以使用已知值优化代码.它还意味着const
具有可见初始化程序的整数对象是编译时常量,标准使用它来将其用作数组大小或模板参数.如果修改const对象不是UB,那么const对象将不会是常量,并且这些事情是不可能的:
#include <iostream>
struct Foo {
int a;
Foo(int a) : a(a) {}
};
void nobody_knows_what_this_does1(const int *p); // defined in another TU
void nobody_knows_what_this_does2(const int *p); // defined in another TU
int main() {
const Foo f(1);
Foo g(1);
nobody_knows_what_this_does1(&f.a);
nobody_knows_what_this_does2(&g.a);
int x;
if (std::cin >> x) {
std::cout << (x / f.a); // Optimization opportunity!
std::cout << (x / g.a); // Cannot optimize!
}
}
Run Code Online (Sandbox Code Playgroud)
因为它f
是一个const对象,因此f.a
是一个const对象,所以优化器知道f.a
在函数末尾使用它时值为1.如果它选择的话,它可以优化分裂.它不知道同样的事情g.a
:g
不是const对象,指向它的指针已被传递给未知代码,因此它的值可能已经改变.因此,如果你的作者nobody_knows_what_this_does1
或者nobody_knows_what_this_does2
,和你想的const_cast
ING p
并用它来修改其referand,那么你只能做,如果你不小心知道referand是非常量.通常你不这样做,所以通常你不使用const_cast
.
归档时间: |
|
查看次数: |
184 次 |
最近记录: |