这是基于我之前的问题:Is this an appropriate use of const qualifiers in C?
在Vector.h
:
typedef struct _Vector Vector;
Vector* vector_init(const UInt32 size);
void* vector_get(const Vector *v, UInt32 idx);
void vector_add(Vector *v, void* const elem);
void vector_set(Vector *v, const UInt32 idx, void* const elem);
...etc
在Vector.c中:
struct _Vector{
UInt32 used;
UInt32 size;
void** arr;
};
Vector* vector_init(const UInt32 size){
Vector* v = malloc(sizeof(Vector));
v->used = 0;
v->size = size;
v->arr = malloc(size*sizeof(void*));
return v;
}
void* vector_get(const Vector *v, const UInt32 idx){
if ( idx >= v->used )
exitAtError("Vector","Array out of bounds");
return v->arr[idx];
}
void vector_add(Vector *v, void* const elem){
if( v->used == v->size )
vector_resize(v);
v->arr[v->used++] = elem;
}
...etc
我希望阻止void** arr
中的_Vector
被我的实现意外修改,作为编译时的警告/错误。我无法使arr
成为const void**
,因为我不希望向量是永久性的,并且希望避免丢弃const。
这里的想法是used
和size
是与我的函数范围直接相关的数据,而arr
只是我不想要的一种元数据修改。 arr
是不透明的,因此我无法直接修改它,但我可以使用memcpy
来强制转换或直接覆盖。
在此示例中,似乎没有必要强制执行此访问,因为每个函数都是直接的,但此示例主要用于演示目的。
我有两个相关问题可以同时回答:
我在Is there a way to protect a class variable from being modified outside of a function
中看到了相关问题该用户似乎在C#中处于类似的困境;我的问题#2与那种情况有关。
编辑:我想从大家的意见来看,我正在通过寻找某种类型的魔法关键字来为我记录内容,从而将语言推到原始设计之外。要么将我的数据隐藏在另一个抽象之后,要么在结构上分离我的功能以防止诱惑数据,这似乎是最好的解决方案。
答案 0 :(得分:1)
main
我猜这种变化会对你有用。否则,使用getter和setter函数的抽象,而不是直接分配给每个函数中的结构成员。这样,你不必担心它。
答案 1 :(得分:0)
我相信你可以做void* const
之类的事情。 const
位置使指针和指针指向的数据不可变。
在我看来(这并不多说),希望指针的数据不被修改似乎是一个合理的愿望,因为它有助于记录代码对传递给它的数据的作用(不是修改它。)
答案 2 :(得分:0)
由于您在C / C ++中寻找解决方案,我在C ++中创建了一个抽象层来保护class array{
public:
void setArray(void** key)
{
arr=key;
}
void** getArray()
{
return &(*arr);
}
private:
void** arr;
};
struct Vector: public array{
int used;
int size;
};
Vector* vector_init(const int size){
Vector* v =(Vector*) malloc(sizeof(Vector));
v->used = 0;
v->size = size;
void** tem=v->getArray();
tem=(void**) malloc(size*sizeof(void*));
v->setArray(tem);
return v;
}
,如下所示。请检查它是否符合您的要求。
For data As Integer = 0 To InvestorGridView.Rows.Count - 1
Response.Write(InvestorGridView.Rows(data).Cells(0).Text)
Response.Write(InvestorGridView.Rows(data).Cells(1).Text)
Response.Write(InvestorGridView.Rows(data).Cells(2).Text)
Next