我需要对现有函数进行修改,输入参数为const
:
int f(const owntype *r1, const owntype *r2)
为了做到这一点,我想调用一个使用相同类型但没有const
关键字的子功能:
void subfunction (owntype *src, owntype *dst)
我已经尝试了这个(以及其他一些变体),但它不起作用:
int f(const owntype *r1, const owntype *r2) {
...
subfunction((const owntyp*) r1);
...
}
如何在不需要更改两个函数的parmeter描述的情况下编译它?
答案 0 :(得分:5)
最佳解决方案是修改subfunction
以指向const
。
在实践中,有时这是不可能的(例如,需要修改由于组织实践而不允许修改的代码)。在这些情况下,您可以写:
subfunction( (owntype *)r1, (owntype *)r2 );
只要您确定subfunction
不修改指向的对象,这是正确的。如果确实尝试修改它们,则会在尝试修改时引起未定义的行为。
如果你不确定subfunction
做了什么,并且你想要防御性地编程,那么另一个选择是获取对象的副本:
owntype c1 = *r1, c2 = *r2;
subfunction( &c1, &c2 );
注意,检查制作副本不会破坏owntype
的类不变量。
其他一些答案/评论表明,抛弃const可能是未定义的行为。但事实并非如此。相关报价为C11 6.7.3 / 6:
如果尝试通过使用具有非const限定类型的左值来使用const限定类型定义的修改对象,则行为未定义。
答案 1 :(得分:3)
只要Map<String,Integer> dataMap=new LinkedHashMap<String,Integer>(); //Your data map
Map<Integer,Integer> countMap=new LinkedHashMap<Integer,Integer>(); //map to count data map entries
//initializing with default value
dataMap.put("a", 1);
dataMap.put("b", 2);
dataMap.put("c", 1);
dataMap.put("d", 2);
dataMap.put("e", 1);
dataMap.put("f", 3);
dataMap.put("g", 1);
//main logic
dataMap.forEach( (k,v) -> {
if(countMap.get(v)==null)
countMap.put(v, 0);
Integer count=countMap.get(v);
countMap.put(v,count+1);
} );
//printing the count
countMap.forEach( (k,v) -> {
System.out.println(k+" "+v);
} );
没有尝试写入指向对象subfunction
和*r1
,就可以通过强制转换来调用它:
*r2
标准(§6.7.3)说:
如果尝试修改用a定义的对象 通过使用具有非const限定的左值的const限定类型 类型,行为未定义。
所以,只要你不写信,就可以从中读取它。
答案 2 :(得分:2)
您已声明subfunction
不会更改输入。这是出于目的/设计还是未来的变化可能会导致修改输入?
在第一种情况下,将输入定义为const
显然是一个错误。
由于subfunction
似乎在您的控制之下:修复界面 - &gt;完成了!
在第二种情况下(接口的const
ness被正确选择)也:不要删除const!对该函数的未来更改可能会在意外的位置上破坏您的代码。而是制作本地副本并将副本用作subfunction
的参数。
答案 3 :(得分:1)
来自评论:
subfunction()不修改上述参数,但它在应用程序中很普遍,并且在每个地方都使用了一个未声明为const的变量。如果我更改了子函数()的签名,我需要对整个程序进行修改,我想避免这种修改。
请注意,为使用const
参数定义的函数提供非const参数是完全正确的。因此,除非subfunction
调用具有非const参数的其他函数,否则如果将参数更改为const
,它将正常工作。
请注意,如果您想在现有代码中引入const
,最简单的方法是自下而上。从最基本的功能(那些不会调用任何其他功能的功能)开始,然后按照调用层次结构的方式工作。这样你可以一点一点地做到这一点。如果你从顶部开始(比如在main
中),代码将不会再次编译,直到你在任何地方都改变它为止。
答案 4 :(得分:-1)
(const owntype *)r1
是免费操作,因为r1
的类型已经是const owntype *
。
被调用函数(subfunction()
)需要类型为owntype *
的参数。您可以将r1
转换为owntype *
作为参数传递给subfunction()
,但如果subfunction()
尝试修改该值,那么您将遇到大麻烦。
稍微考虑两个函数的接口。
int f(const owntype *r1, const owntype *r2)
说:&#34;给我两个owntype
对象(r1
和r2
)的地址,我保证我不会改变对象( const
)&#34;
然后它在内部将r1
和r2
传递给subfunction()
。 subfunction()
没有对其参数指向的值做出任何承诺(那里没有const
),并且可以随意更改它们。然后它返回并且f()
在不知情的情况下违背其承诺。
这不是事情的运作方式,这就是为什么从const
转为非const
undefined behaviour的原因。