【问题标题】:2 simple variable initialization question [duplicate]2个简单的变量初始化问题[重复]
【发布时间】:2011-07-05 09:12:14
【问题描述】:

可能重复:
Is there a difference in C++ between copy initialization and direct initialization?

有什么区别,

int x(5);
int x = 5;

&有什么区别,

int const x(5);
const int x(5);

【问题讨论】:

  • 因为我想知道这两种观点。
  • 如果问题只是第一部分,那么否决票可能是可以的。但是,如果您按照问题第二部分的答案进行操作,那么这个否决票是错误的。

标签: c++


【解决方案1】:

在您显示的 4 行中,只有 1 行是有效的 C。

int x(5);        /* INVALID C */
int x = 5;
int const x(5);  /* INVALID C */
const int x(5);  /* INVALID C */

我不知道其他语言中无效行的含义。在 C 中,有效行的含义是创建一个名称为x、类型为int、值为5 的对象。


要定义一个“const”(更好的是:一个“只读”)对象,C 语法是

const int x = 5;
int const x = 5;

但是x 不能用在只允许使用常量的地方。 x 不是一个常数:它是一个const int

类型的对象
#define CONSTANT 42
enum /*unnamed*/ { First=1, Second, Third };
switch (var) {
    case x: break; /* invalid use of x; only constants allowed in case labels */
    case 15: break; /* ok; 15 is a constant */
    case CONSTANT: break; /* ok; CONSTANT is a constant with value 42 */
    case Second: break; /* ok; Second is a constant with value 2 */
}

【讨论】:

  • 是,const int x = 5 在 C 中有效吗?
  • 是的,它创建了一个名为x的对象,其值为5,限定类型为const int。注意(不合格或基本)类型仍然是int;它不会创建一个常量(例如,可用于案例标签):它会创建一个无法通过该标识符更改的对象。
  • 要使用case x: break;,我必须使用const int x = 5;吗?
  • @iamcreasy:不,在 C 中,类型限定符 const 不会创建常量。它创建了一个不能通过其定义名称更改其值的对象。 Objects 不能用于需要 constants 的地方。当您需要一个实常数时,请使用其他选项之一。
【解决方案2】:

关于const 的一个非常好的经验法则:

从右到左阅读声明。

(参见 Vandevoorde/Josutiss “C++ 模板:完整指南”)

例如:

int const x; // x is a constant int
const int x; // x is an int which is const

// easy. the rule becomes really useful in the following:
int const * const p; // p is const-pointer to const-int
int const &p;        // p is a reference to const-int
int * const * p;     // p is a pointer to const-pointer to int.

自从我遵循这条经验法则以来,我再也没有误解过这样的声明。

(: sisab retcarahc-rep a no ton ,sisab nekot-rep a no tfel-ot-thgir naem I hguohT :tidE

【讨论】:

  • @iamcreasy:你的评论有错别字。
  • @martinho-fernandes Read Right-to-Left.
  • @iamcreasy。我做到了。里面有错别字。现在修复它为时已晚:P
  • 啊,:|现在无法编辑帖子! :P 这次让我们滑动。
【解决方案3】:

首先,内置类型没有区别。对于类类型,T x = y 表示法需要复制构造函数,T x(y) 表示法不需要。 编辑:另外,正如其中一位评论者指出的那样,如果 T(y) 构造函数被声明为 explicitT x = y 将不起作用。

对于第二个,就编译器而言没有区别,但第二个 (const int) 在很多情况下会导致混淆,尤其是在涉及 typedefs 时,例如:

typedef int* IntPtr;
IntPtr const cpi1;  //  Const pointer to a non-const int.
const IntPtr cpi2;  //  Also a const pointer to a non-const int.

在这两个定义中,const 适用于指针。

由于这种混淆,通常认为更好的做法是将 const 放在它修改的内容之后。现在——很长一段时间以来,把const放在开头是很常见的,结果这种做法很普遍。

【讨论】:

  • const 开头也是标准中通常的写法。
  • "对于类类型,T x = y 表示法需要复制构造函数,T x(y) 表示法不需要。"事实并非如此。两者都需要一个复制构造函数。 T x = y 看起来像赋值,但不是一个。
  • @Fernandes 是的,标准是基于ARM的。似乎不值得费心去改变(有些年长的程序员已经习惯了const int,如果我们真的改变了,他们会觉得不舒服)。 “普遍接受”的最佳实践已更改为支持 int const,但不会因使用 const int 而受到批评,或者值得更改现有代码中的实践。
  • @Rafal T x(y) 不需要复制构造函数。它需要一个可以用y 具有的任何类型调用的构造函数。 T x = y 需要一个可访问的复制构造函数。 (而且没有人说任何关于作业的事情。)
  • @James 很高兴知道这个建议。我想我以后会更加小心:) 另外,您可能想提一下 T x = y;如果涉及到对显式构造函数的调用,则将不起作用。
【解决方案4】:

在您使用参数之前,两者都不完全相同。这只是编码风格的问题。

[注:但以下不一样:

int x;  // x is variable
int x();  // x is function declaration

]

【讨论】:

  • 这是一个更好的答案,因为它会引发有用的警告。
【解决方案5】:

关于const 关键字:

  • 它使 const 立即位于其 左侧
  • 如果左侧没有任何内容,则适用于右侧

所以,int const iconst int i 是相同的。

但是,int *const iconst int *i 不一样:在第一个表达式中,指针是常量,在第二个表达式中,指向的整数是常量。 als int const* i 相当于第二个。

【讨论】:

  • * 字符,它先在哪一边起作用?左还是右?
  • * 或者跟在 类型名称 之后:在这种情况下,它是一个类型修饰符(将类型修改为指针类型),或者跟在 表达式:在这种情况下,它是乘法运算符,或者位于绑定到指针类型的表达式之前:它是 dereference 运算符。没有这样的规则。
  • int *const i : i 是一个 const 指针,它指向一个非常量 int & int const* i : i 是一个指针,它指向一个 const int。对吗?
  • @iamcreasy:是的。很多人都这么说!
【解决方案6】:

没有区别。将变量初始化为值的替代方法。

但是你在你的系统上试过这个吗?你得到了什么?

【讨论】:

  • 我试过了,它们是一样的。我认为背后可能隐藏着一些技术细节。
【解决方案7】:

在 c++ 中没有区别,但是在 c 中 - int x(5); 是不允许的

【讨论】:

    【解决方案8】:
    int x(5);
    int x = 5;
    

    没有区别。

    int const x(5);
    const int x(5);
    

    没有区别。

    int x = 5;
    const int *p = &x;
    int *const q = &x;
    

    这是pq 的区别。使用p 不能更改x 的值,但可以为p 分配一个新地址。使用q,您不能指向任何其他内存位置,但您可以使用q 修改x

    【讨论】:

    • 你的第三个例子没有区别。
    • @martinho fernandes:已修复。谢谢。 :)
    • -1 最后一段是完全错误的。
    • @james kanze:编辑后出错?怎么了?
    • 我看了看评论说错了。重要的是int constconst int 含义相同。不管接下来会发生什么。
    猜你喜欢
    • 2016-12-12
    • 2021-04-07
    • 2021-09-04
    • 1970-01-01
    • 1970-01-01
    • 2010-10-31
    • 2015-03-10
    • 1970-01-01
    • 2011-03-18
    相关资源
    最近更新 更多