是否有一种简单的方法可以将非const C ++结构(通过指针)传递给函数,并确保该函数不能更改结构的成员?
Ex:从配置文件加载结构,这需要结构为非const。但是然后一个指向结构的指针被传递给一个不允许改变任何东西的函数。
我已经通过创建结构的第二个逐字“const”副本以及繁琐地复制每个成员来完成此操作。这看起来很奇怪。我是C#程序员,所以也许这就是在C ++中完成的方式......?
答案 0 :(得分:6)
在C ++中,您可以传递大对象作为引用或指针,两者都被称为"通过引用调用"与"按价值呼叫"复制的地方。指针语法由C语言继承,与C ++引用不同。
要让编译器抱怨您对象的更改,您必须使用const
关键字。当然,无论如何你都可以投放const
来改变价值观,但是根本不建议投放const
。
我们假设以下示例中您有一个类BigObject
,其公共成员a
是一个整数int
。
<强> 1。 通过引用打电话(&amp;:参考类型):
void function(const BigObject& input)
{
int a = input.a; /* read from BigObject */
input.a = 42; /* the compiler will fail! */
}
/* call that function */
BigObject input();
function(input); /* no address operator needed */
const
关键字会使引用&
(此处不是地址运算符)引用此引用无法更改的数据。如果您尝试编译器将无法编译。
<强> 2。 按引用调用(*:指针类型):
void function(const BigObject* input)
{
int a = input->a; /* read from BigObject */
int b = (*input).a /* alternative to -> */
input->a = 42; /* the compiler will fail! */
}
/* call that function */
BigObject input();
function(&input); /* pass address */
参数是指针类型,指向不能被此指针更改的数据。您还可以使用:const BigObject* const input
使指针保持不变,有关此内容的更多说明如下。
以下是引用和指针之间的区别:
operator *
或->
来完成类/结构成员,请参阅上面的代码。&
传递对象的地址才能获得指针。NULL
它们必须有效,但指针可以指向NULL
。 const
关键字的展示位置
const
关键字的位置决定了什么应该是常量,指针或指针指向的对象。
一般来说,如果您只想到穿过*
(星号)的垂直线,则可以更容易记住以下内容。如果const
位于*
的左侧,则它将应用于类型(对象),如果它位于右侧,则它将应用于指针:
|
BigObject * input /* pointer to BigObject */
const BigObject * input /* pointer to constant BigObject */
BigObject const * input /* same as before, I don't use this */
BigObject * const input /* constant pointer to BigObject */
|
你也可以结合起来使它们保持不变:
|
const BigObject * const input /* constant pointer to constant BigObject */
|
const
关键字的展示位置与参考文献无关。 reference is always constant(这是隐式的,未明确命名),意味着一旦设置它就无法引用另一个对象。然而,该对象是可变的。这意味着const
右侧的&
关键字将是多余的,不会更改任何内容,只是不要使用它。你应该区别对待:
BigObject& input /* reference to BigObject */
const BigObject& input /* reference to constant BigObject */
BigObject const & input /* same as before, I don't use this */
答案 1 :(得分:3)
解决方案很简单:将指向const的指针传递给函数(或者,或许引用更合适)。该函数将无法通过指向const的指针修改对象。