繁体   English   中英

在C ++中使用const的正确方法是什么?

[英]What's the correct way to use const in C++?

const正确让我有些困惑。

您使用什么经验法则来决定什么时候应该是const?

例如,考虑这个例子

class MyClass
{
  string ToString(); // this one?
  const string& ToString(); // or this? 
  const string& ToString() const; // or this?

  char* ToString(); // What about this?
  const char* ToString(); // or this?
  const char* ToString() const; // or this?
  const char const* ToString(); // Is this legal?
  const char const* ToString() const; // how about this?
  char const* ToString();  // or even this?
};

Const可能会让人感到困惑。

所有这些ToString方法之间有什么区别?

如果我理解正确,第一个返回一个新的字符串对象,如果需要可以修改。 第二个返回一个常量引用,也许它应该是字符串const和ToString()。 第三个可能是废话,因为引用总是不变的是正确的吗?

以为我会把旧的char *版本放在那里进行比较,因为我有返回对象指针的方法,我不确定它们是否应该是const。

我想我只是想了解const正确性的局限性和好处,以及如何预先确定某些东西是否应该是const以及如何正确地应用const,因为将const放在不同的位置会改变含义。

编辑:另外,我如何处理'...丢弃限定符'。 这究竟意味着什么?

使用const取决于函数的用途。 正如詹姆斯在他的评论中所建议的那样(值得作为答案),将const放在任何地方:

如果该函数旨在修改其对象实例中的状态, 请不要const放在签名的末尾。

如果该函数旨在修改其中一个引用或指针参数, 请不要在参数上放置const

如果通过指针或引用所引用的变量应该被修改, 不要const的类型(记住, const适用于定义之前立即的一部分)。

如果返回的引用/指针引用不应该由接收改变一个变量, 不要const的类型。

在不知道功能的目的的情况下,回答问题中给出的例子是不可能的。 我倾向于使用string ToString() constchar* ToString() const ,以及关于谁负责delete char*非常明确的文档。


另外, const char*char const*是相同的(指向不可修改字符的指针)。 另一方面, char* const是一个指向可修改字符的不可修改的指针。

我一直用这个常见问题解答来解决这些类型的问题。 http://www.parashift.com/c++-faq-lite/const-correctness.html

您不能重载具有相同名称和相同参数但返回类型不同的函数。 你可能知道这一点,但只是确定。

()括号后的const表示该函数不会更改您调用它的对象。 通常称为ToString东西不会改变对象,所以在所有情况下你可能都想要一个const方法。

返回string和返回const string&之间的区别在于引用没有和对象复制并且可能更快,但是只有在已经有string对象(例如,作为MyClass的私有成员)时才能执行此操作。 如果不是(比如你需要将几位数据拼凑在一起,然后返回该字符串),你需要按值返回string

使用string对象通常比使用C样式的char*指针更好,但是因为你问:第四个, char* ,会让其他代码更改返回字符串中的字符,这可能是一件坏事。 const char*char const*const char const*都是一样的。 char *const在技​​术上是不同的,但它不会作为返回类型做太多,因为返回const int并不重要:调用者可以只复制然后更改返回值。

简而言之,最好的形式将是:

const string& ToString() const;
string ToString() const;
const char* ToString() const;

问题的一些变化是返回stringchar * 我认为这与const讨论无关(如果不是,请告诉我); 我正在考虑string返回变化。

class MyClass
{
  string ToString();              // A
  string & ToString();            // B   (I added this)
  const string& ToString();       // C 
  const string& ToString() const; // D
};

我的喜好按此顺序排列:D,C,B,A。

在所有变体中, const以两种方式使用:

  • 返回类型说明符[D中的第一个const ]

    这意味着返回的对象不能用于修改返回的对象。 这句话听起来很有趣,不是吗? 好吧,可能还有其他修改对象的方法,这个const无法阻止它。 请参阅此FAQ项目

  • class invariant [D中的第二个const ]

    这意味着该方法不会改变(修改)类对象。

我更喜欢D而不是其他任何因为D保证不会修改调用该方法的对象。 如果可以在不修改对象的情况下实现目标(即可以实现方法),那么在设计方面就是一个巨大的胜利。 我尽可能地使用它。 但是如果必须修改对象(即,如果不修改对象就无法实现该方法),则排除D。

其余的B和C都优于A,因为B和C返回一个引用,这避免了A中所需的复制构造。

在B和C之间,C是优选的,因为它返回const参考。

我发现是一个有用的指南

您使用什么经验法则来决定什么时候应该是const?

尽可能地使用它。 然后,当您需要修改对象或授予对可能修改对象的内容的访问权限(即将引用或代理返回到内部状态)时, 请不要使用它。

第三个可能是废话,因为引用总是不变的是正确的吗?

不,这不正确。 引用是别名,而不是变量。 因此,您无法更改引用“指向”哪个变量,就像使用指针一样。 但是,您可能引用了一个可变对象( std::string& )。

所有这些ToString方法之间有什么区别?

它们在内存管理技术方面差异很大,但在高级别,它们都做同样的事情,除了以下内容:

char* ToString();

那个ont返回一个指向可变数组字符的指针(可能是内部状态)。

请注意以下系列:

char const* ToString();
const char* ToString(); // or this?
const char const* ToString(); // Is this legal?

写出同样的东西都是不同的方式。 无论你是否写入,本地类型都是按值返回的const。

以下2是C ++中返回字符串的首选方法(在最后提供了一个额外的const ):

string ToString(); // this one?
const string& ToString(); // or this?

您将使用哪两个取决于您从哪里获得价值。 如果字符串是数据成员,我建议你选择后者,因为它通常更快,但如果你的字符串实现使用Copy-On-Write语义则不是很多。 如果必须计算一个值并将其返回,则必须使用前者,因为您无法返回对局部变量的引用。

以下两个是正确的,但我仍然建议你使用std::string

const char* ToString() const; // or this?
const char const* ToString() const; // how about this?

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM