将 const 引用传递给函数
Passing const references to functions
我在看视频看到这段代码:
class Dog {
public:
Dog() : age(3), name("dummy") {}
void setAge(const int &a) { age = a; }
private:
int age;
std::string name;
};
我对 setAge
的函数签名很好奇,因为我从未将 const
用作函数参数。我查看了几个相关的答案,但 none 似乎回答了我的问题。
在这样一个基本示例中,很难看出将 const
引用传递给函数的好处。
您是否有任何理由想要将 参考文献 设为 const
?我能想到的唯一应用是在嵌入式编程中,当复制变量时可能会浪费宝贵的 space.
是否有任何简单的例子,也许可以很容易地看出传递 const
引用的影响?
考虑一个占用大量内存的对象。您需要将它传递给一个函数——一个只会提取一些信息而不会以任何可能的方式更改对象的函数。在这种情况下,const
参考是一个很好的选择。
std::vector
可以是一个例子,Matrix对象是另一个例子。
void setAge(const int &a) { age = a; }
您正在传递 const int reference
,您不打算修改函数 setAge
内的值 a
。
void setAge(int &a) { age = a; }
您正在传递一个 int reference
,您不关心函数 setAge
是否修改函数 setAge 中的值 a
。
做 const 的正确性是一个很好的编程实践,作为更好的接口定义的实践。第一个函数签名传达的信息非常清楚,第二个与第一个相比比较模糊。
您可以在此处阅读有关 const 正确性的更多信息 https://isocpp.org/wiki/faq/const-correctness#overview-const
复制变量会浪费宝贵的space并浪费宝贵的时间,这就是为什么在任何编程中都需要担心避免不必要的复制,不只是嵌入式的。因此,使用 const T &
引用来传递只读参数一直是 C++ 中的惯用语。
但是,它通常保留用于传入 "heavy" 对象,即复制成本相对较高的对象。将它与标量类型一起使用(如您的示例)几乎没有意义。
考虑以下三个示例:
(i) void setAge(int &a) { age = a; }
(ii) void setAge(const int &a) { age = a; }
(iii) void setAge(int a) { age = a; }
进一步把你的class想象成一个封装对象,也就是外面的世界一般不知道里面发生了什么。
然后,使用案例(i)
,调用者无法知道a
之后没有被改变。
int a=3;
dog.setAge(a); //case (i): what is "a" afterwards?
我们不知道函数调用后 a
的值是什么 -- 事实上,函数签名告诉调用者可能会发生 a
的更改。
另一方面,通过使用变体(ii)
,您再次通过引用传递对象,即您不进行复制,而是告诉函数它可以访问的内存地址范围。与案例 (i)
相反,现在您确保调用者 "nothing is going to happen to your parameter"。也就是说,您之后可以安全地使用该参数,并确保它仍然具有与以前相同的值(——至少在原则上,函数内部也可能发生像 const_cast
这样的坏事)。
最后,在 (iii)
的情况下,复制 int
并在函数内部使用它。对于像 int
这样的内置类型,这实际上是传递函数参数的首选方式。但是,如果对象的复制成本很高,它可能无效。
关于整个 const 正确性-主题,请参阅 here。
我在看视频看到这段代码:
class Dog {
public:
Dog() : age(3), name("dummy") {}
void setAge(const int &a) { age = a; }
private:
int age;
std::string name;
};
我对 setAge
的函数签名很好奇,因为我从未将 const
用作函数参数。我查看了几个相关的答案,但 none 似乎回答了我的问题。
在这样一个基本示例中,很难看出将 const
引用传递给函数的好处。
您是否有任何理由想要将 参考文献 设为 const
?我能想到的唯一应用是在嵌入式编程中,当复制变量时可能会浪费宝贵的 space.
是否有任何简单的例子,也许可以很容易地看出传递 const
引用的影响?
考虑一个占用大量内存的对象。您需要将它传递给一个函数——一个只会提取一些信息而不会以任何可能的方式更改对象的函数。在这种情况下,const
参考是一个很好的选择。
std::vector
可以是一个例子,Matrix对象是另一个例子。
void setAge(const int &a) { age = a; }
您正在传递 const int reference
,您不打算修改函数 setAge
内的值 a
。
void setAge(int &a) { age = a; }
您正在传递一个 int reference
,您不关心函数 setAge
是否修改函数 setAge 中的值 a
。
做 const 的正确性是一个很好的编程实践,作为更好的接口定义的实践。第一个函数签名传达的信息非常清楚,第二个与第一个相比比较模糊。
您可以在此处阅读有关 const 正确性的更多信息 https://isocpp.org/wiki/faq/const-correctness#overview-const
复制变量会浪费宝贵的space并浪费宝贵的时间,这就是为什么在任何编程中都需要担心避免不必要的复制,不只是嵌入式的。因此,使用 const T &
引用来传递只读参数一直是 C++ 中的惯用语。
但是,它通常保留用于传入 "heavy" 对象,即复制成本相对较高的对象。将它与标量类型一起使用(如您的示例)几乎没有意义。
考虑以下三个示例:
(i) void setAge(int &a) { age = a; }
(ii) void setAge(const int &a) { age = a; }
(iii) void setAge(int a) { age = a; }
进一步把你的class想象成一个封装对象,也就是外面的世界一般不知道里面发生了什么。
然后,使用案例(i)
,调用者无法知道a
之后没有被改变。
int a=3;
dog.setAge(a); //case (i): what is "a" afterwards?
我们不知道函数调用后 a
的值是什么 -- 事实上,函数签名告诉调用者可能会发生 a
的更改。
另一方面,通过使用变体(ii)
,您再次通过引用传递对象,即您不进行复制,而是告诉函数它可以访问的内存地址范围。与案例 (i)
相反,现在您确保调用者 "nothing is going to happen to your parameter"。也就是说,您之后可以安全地使用该参数,并确保它仍然具有与以前相同的值(——至少在原则上,函数内部也可能发生像 const_cast
这样的坏事)。
最后,在 (iii)
的情况下,复制 int
并在函数内部使用它。对于像 int
这样的内置类型,这实际上是传递函数参数的首选方式。但是,如果对象的复制成本很高,它可能无效。
关于整个 const 正确性-主题,请参阅 here。