如何解决什么时候以及为什么要使用String&,String和Const?
我正在编写一段代码。
struct Argument
{
Argument(): s_name(""),name(""),optional(true) {}
Argument(String& s_name_inp,String& name_inp,bool optional_inp):s_name(s_name_inp),name(name_inp),optional(optional_inp){}
.....More code.....
}
稍后在代码中的某个地方
void addArgument(String& name_inp,bool optional=true)
{
String name;
//Creating a tmep string to store the corrected name if the user doesn't enter - or -- wrt. name of their argument.
name = isDashed(name_inp) ? name_inp : addDash(name_inp) ;
//using the dashed name to check if it's shortname or long name.
if(name.size()>3)
{
//This is the long name.
Argument arg("",name,optional);
insertArgument(arg);
}
else
{
//This is for the short name
Argument arg(name,"",optional);
insertArgument(arg);
}
}
Struct Argument和fn addArgument都是类的一部分,其中struct Argument在private中定义,而addArgument在公共中定义。
运行代码时抛出错误。 对于长名-
error: no instance of constructor "ArgumentParser::Argument::Argument" matches the argument list
argument types are: (const char [1],ArgumentParser::String,__nv_bool)
一个简称--
error: no instance of constructor "ArgumentParser::Argument::Argument" matches the argument list
argument types are: (ArgumentParser::String,const char [1],__nv_bool)
我可以弄清楚如何解决它。由于输入了空字符串""
,因此出现此错误。在struct Argument构造函数中添加const可以解决此问题。
struct Argument
{
Argument(): s_name(""),optional(true) {}
Argument(const String& s_name_inp,const String& name_inp,optional(optional_inp){}
.....More code.....
}
类似地,声明一个String blank = "" ;
并在初始化struct Argument而不是""
的obj时传递它也可以解决该问题。另外,在Argument构造函数中传递String而不是String&也可以解决问题-
Argument(String s_name_inp,String name_inp,optional(optional_inp){}
因此,我由此得出的结论是,仅传递""
是一个问题,因为它没有存储在某些变量中。它没有某些可以引用的位置(字符串和),以防代码内部发生更改。这就是为什么在构造函数的String&之前添加一个const可以确保即使我们通过ref传递,编译器也不会进行任何更改,因此编译器允许使用""
。
但是,即使我没有执行任何不正确的操作,我也不明白为什么编译器如此“智能”。就像编译器也在弹出“安全性”漏洞一样,除了我们经常犯的“错误”。
关于这个问题,我也想从更广泛的意义上理解const
的使用。
我明白这只是为了确保不会更改要传递(或返回)给函数/构造函数的变量。但是,如果我作为程序员可以确保我不会更改变量,为什么我们需要它。那么为什么我们需要const?
我知道的一件事是,它可以用来告诉其他人,如果他们看到您的代码,则保持参数不变。(https://www.youtube.com/watch?v=4fJBrditnJU是学习const的良好来源)而且,使用之间有什么区别这两种情况下const
中的-
int somefunc const(int& var)
{
// var=4; This isn't allowed due to the const in fn
return var;
}
int somefunc(const int& var)
{
// var =4 ; This is also not allowed.
return var;
}
此外,我想知道如果引用引用和值传递仅用于赋值,即它们没有进行任何更改,而是用于检查条件或对它们进行某些赋值,则它们之间有何不同?其他变种。
添加const String&就像保证,无论用户传递的是什么,在代码中都不会被篡改,因此我们不能简单地用String替换它吗?因为按值传递将实例化传递的变量/参数的副本?为什么我们使用const String&then?
关于传递指针和通过引用传递的另一个问题:我知道的String&(或int&或任何其他)的唯一用途是直接将实际的“事物”传递给函数,而不是其副本,因此无论我们做什么该“事物”将反映在原始事物上,就像我们使用指针来获取对实际“事物”所做的更改一样,而不是对其进行复制。为什么我们不使用指针而不是通过引用传递?它带来什么好处?
我知道这个问题有点大,但这些都是相互关联的问题。回答一个就称赞另一个。感谢任何花时间回答他们认为合适的人!
解决方法
在大多数情况下,指针和l值引用可以互换。只需在调用位置编写即可。
正如您所注意到的,const &
和&
之间的区别来自一个简单的引用,该引用需要变量进行引用。带有&
的引用的语义是“让我为您写下来”。 const &
允许即时创建临时副本,其语义为“让我看看”。价值传递的含义是“给我一份副本,我决定如何处理”。
根据实际经验,避免复印是您的首要考虑。因此,对于大于整数值的值,您应该避免按值调用。
常量正确性主要只是C ++语言的设计,从技术角度来看并不是严格要求的。您可以认为它是一种表达“相信我,我不会破坏它”的方式。
关于将临时值传递给简单的&
参数,请先仔细考虑一下谁真正拥有该临时值,以及将存在多长时间。如果允许您写入任何内容,将会丢失。
还要考虑默认参数,例如void foo(const bar &foobar = bar(42))
。绝对不允许将它们作为非const引用,因为这会导致未定义的行为。该默认对象可能存在于静态范围内(而不是每个调用者都重新创建它),并且有人弄乱了它会导致更改默认值。祝您找到该错误的根源。
即使对于非默认参数,const &
允许在编译时创建临时变量(constexpr
构造函数),也可以将相同临时对象的多个实例折叠到内存中的单个实例中。没有const
的保证,这种优化同样是不可能的。
还有很多其他情况,其中const
-正确性也是启用编译器优化的关键。因此,即使您认为自己的代码纪律至少会阻止未定义的行为,通常也要正确使用它。
但是,如果我作为程序员可以确保我不会更改变量,为什么我们需要它。那么为什么我们需要const?
您还可以确保在编码中不犯任何错误,因此为什么要进行编译器错误/警告,单元测试,问题跟踪器……
- Why would you use the keyword const if you already know variable should be constant?
- Use const wherever possible in C++?
添加const String&就像保证,无论用户传递的是什么,在代码中都不会被篡改,因此我们不能简单地用String替换它吗?因为按值传递将实例化传递的变量/参数的副本?为什么我们使用const String&then?
- 与引用上的间接引用相比,复制一个类可能会更昂贵。尤其是如果在
const &
情况下编译器能够内联函数的情况下,根本不会发生任何间接作用。 - 副本可能会带来不良的副作用(在资源有限的环境中可能会出现问题)
- 一个类可能有一个删除的副本构造函数,因此根本不可能复制,但是您仍然要确保const正确性。
我对String&(或int&或其他任何字符)的唯一了解是直接将实际的“事物”传递给函数,而不是函数的副本,因此我们对“事物”所做的任何操作都将反映在原始,就像我们使用指针来获取要对实际“事物”进行的更改一样,而不是对其进行复制。为什么我们不使用指针而不是通过引用传递?它带来什么好处?
指针可以接受nullptr
,因此您需要处理传递nullptr
的情况(如果不必传递nullptr
,则可以使用gsl::not_null
)。但是使用指针不允许传递临时变量。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。