C/C++:Const 结构中的指针

发布于 2024-09-08 04:09:06 字数 951 浏览 3 评论 0原文

如何强制函数 fn 中 obj->val1 指向的内存保持常量?

#include <iostream>

struct foo {
    int* val1;
    int* val2;
    int* val3;
};

void fn( const foo* obj )
{
    // I don't want to be able to change the integer that val1 points to
    //obj->val1 = new int[20]; // I can't change the pointer,
    *(obj->val1) = 20; // But I can change the memory it points to...
}

int main(int argc, char* argv[])
{
    // I need to be able to set foo and pass its value in as const into a function
    foo stoben;
    stoben.val1 = new int;
    *(stoben.val1) = 0;
    std::cout << *(stoben.val1) << std::endl; // Output is "0"
    fn( &stoben );
    std::cout << *(stoben.val1) << std::endl; // Output is "20"
    delete stoben.val1;
    return 0;
}

这里的代码非常不言自明。我需要能够创建一个非常量对象并用数据填充它,然后将其传递给无法修改该数据的函数。我该怎么办?

我知道我可以只传递一个 const int 指针,但理论上,这个类包含我在“fn”中也需要的几个其他指针。

谢谢,

格里夫

How do I force const-ness of the memory pointed to by obj->val1 in the function fn?

#include <iostream>

struct foo {
    int* val1;
    int* val2;
    int* val3;
};

void fn( const foo* obj )
{
    // I don't want to be able to change the integer that val1 points to
    //obj->val1 = new int[20]; // I can't change the pointer,
    *(obj->val1) = 20; // But I can change the memory it points to...
}

int main(int argc, char* argv[])
{
    // I need to be able to set foo and pass its value in as const into a function
    foo stoben;
    stoben.val1 = new int;
    *(stoben.val1) = 0;
    std::cout << *(stoben.val1) << std::endl; // Output is "0"
    fn( &stoben );
    std::cout << *(stoben.val1) << std::endl; // Output is "20"
    delete stoben.val1;
    return 0;
}

The code here is pretty self explanitory. I need to be able to make a non-const object and fill it with data, but then pass it to a function where this data cannot be modified. How can I go about this?

I know I can just pass in a const int pointer, but theoretically, this class contains several other pointers which I will need in "fn" as well.

Thanks,

Griff

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

云巢 2024-09-15 04:09:06

由于您标记为 C++,因此您可以将成员设为 private 并创建一个返回 const int * 的访问器。您最初可以通过构造函数或 friend 函数设置该成员。

Since you tagged as C++, you could make the member private and make an accessor that returns a const int *. You could originally set the member via your constructor or a friend function.

南烟 2024-09-15 04:09:06

我不是 C++ 人员,但在 C 中,我会通过两种不同的结构声明来处理这个问题,一种是公共的,一种是私有的:

#include <stdio.h>
#include <stdlib.h>

struct private_foo {
    int* val1;
    int* val2;
    int* val3;
};

struct public_foo {
    int const * const val1;
    int const * const val2;
    int const * const val3;
};


void fn( struct public_foo * obj )
{
    int local;
    *(obj->val1) = 20; // compile error
    obj->val1 = &local; // compile error
}

int main(int argc, char* argv[])
{
    // I need to be able to set foo and pass its value in as const into a function
    struct private_foo stoben;
    stoben.val1 = malloc(sizeof(int));
    if (!stoben.val1) { return -1; }
    *(stoben.val1) = 0;
    printf("%d", *(stoben.val1) );
    fn( (struct public_foo *) &stoben );
    printf("%d", *(stoben.val1) );
    free(stoben.val1);
    return 0;
}

当我尝试使用 GCC 编译上述内容时,我收到以下编译器错误,因为我'我试图修改只读内存:

temp.c: In function ‘fn’:
temp.c:20: error: assignment of read-only location
temp.c:21: error: assignment of read-only member ‘val1’

I'm not a C++ person, but in C, I'd handle this through two different struct declarations, one public, one private:

#include <stdio.h>
#include <stdlib.h>

struct private_foo {
    int* val1;
    int* val2;
    int* val3;
};

struct public_foo {
    int const * const val1;
    int const * const val2;
    int const * const val3;
};


void fn( struct public_foo * obj )
{
    int local;
    *(obj->val1) = 20; // compile error
    obj->val1 = &local; // compile error
}

int main(int argc, char* argv[])
{
    // I need to be able to set foo and pass its value in as const into a function
    struct private_foo stoben;
    stoben.val1 = malloc(sizeof(int));
    if (!stoben.val1) { return -1; }
    *(stoben.val1) = 0;
    printf("%d", *(stoben.val1) );
    fn( (struct public_foo *) &stoben );
    printf("%d", *(stoben.val1) );
    free(stoben.val1);
    return 0;
}

When I try to compile the above w/ GCC, I get the following compiler errors, since I'm trying to modify read-only memory:

temp.c: In function ‘fn’:
temp.c:20: error: assignment of read-only location
temp.c:21: error: assignment of read-only member ‘val1’
陪我终i 2024-09-15 04:09:06

你真的不能。 const foo 指定里面的成员是 const,即它们是指向整数的常量指针,而不是指向常量整数的指针。

对此的正确解决方案是通过封装、隐藏这些成员并提供公共接口。如果您被禁止修改 struct foo,一个实用的解决方案是通过私有继承:

struct foo {
    int* val1;
    int* val2;
    int* val3;
};

struct constFoo : private foo {
public:
   const int* getVal1() { return val1; }
   const int* getVal2() { return val2; }
   const int* getVal3() { return val3; }
};

当然,您需要创建适当的构造函数等,以便可以设置原始 foo。

You really can't. A const foo specifies that the members inside are const, that is, they are constant pointers to integers, not pointers to constant integers.

The proper solution to this would be via encapsulation, hiding these members and providing a public interface. A practical solution, should you be forbidden to modify the struct foo, would be through private inheritance:

struct foo {
    int* val1;
    int* val2;
    int* val3;
};

struct constFoo : private foo {
public:
   const int* getVal1() { return val1; }
   const int* getVal2() { return val2; }
   const int* getVal3() { return val3; }
};

Of course, you would need to create the appropriate constructors, etc., so that the original foo can be set up.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文