作者热门文章
- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我有一些看起来像这样的类(class):
struct A {
void *stuff;
int x;
int foo() const;
}
我有一些采用这种类型参数的函数,例如
int bar(A a1, A2 a2);
int baz(A2 a2);
问题是,并非所有这些函数实际上都改变了
a2.stuff
中的任何内存。 ;然而 - 我不能接受
const void*
和一个
int
, 构造一个 A 并将其传递给此类函数。或者更确切地说,我可以,但只能使用
const_cast<>
这真的不是你生活的方式。另外,我很容易混淆并通过我的
const_cast<>
'ed A 到一个实际修改数据的函数
A::stuff
.
T
- 那么没问题,你更换
A<void>
与 A
<const void>
而 Bjarne 是你的叔叔。但是... A 不是模板化的。我不想让它模板化,因为我不想
A<int>
的或类似的东西存在。
const_A
复制 A 的定义。 :
struct const_A {
void const *stuff;
int x;
int foo() const;
}
struct A {
void *stuff;
int x;
int foo() const;
operator const_A() const { return const_A { stuff, x }; }
}
但这是重复的,如果我有 20 种方法,重复起来就更烦人了。
最佳答案
基于 std::experimental::propagate_const
思想的解决方案:
namespace detail {
struct const_propagating_void_ptr {
void* ptr;
operator void *() { return ptr; }
operator void const *() const { return ptr; }
};
} // namespace detail
struct A {
detail::const_propagating_void_ptr stuff_;
int x;
int foo() const;
void * stuff() { return stuff_; }
void const * stuff() const { return stuff_; }
};
优点:
A
和类似指针的类只是普通的旧结构! const A a1 {my_ptr, 123};
A a2 {a1};
*a2.stuff() = 456; // ... and a1's pointer is used for write access :-(
这个 compiles without warnings 。感谢@AyxanHaqverdili 指出这一点。 const A
和 const void*
(没有 const_cast'ing)构造 int
。 std::experimental::propagate_const
来禁用它,它可能有一个 protected 数据成员,覆盖赋值和移动赋值运算符等。A
中使用 getter 并使用
void*
?
A
的用户很容易犯访问
A::stuff_
而不是
A::stuff()
的错误。如果那只是一个
void *
,那么意外写入
A::stuff_
的几率会很高。但是使用此解决方案,要获得
void*
,您需要编写:
A::stuff_::ptr
,并且没有人会错误地编写
my_a.stuff.ptr
而不是
my_a.stuff()
。
关于c++ - 如何使用类的常量裁判和非常量裁判版本避免 DRY?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68226516/
我是一名优秀的程序员,十分优秀!