const 正确性: const char const * const GetName const (//stuff);

Posted

技术标签:

【中文标题】const 正确性: const char const * const GetName const (//stuff);【英文标题】:Const correctness: const char const * const GetName const (//stuff); 【发布时间】:2009-12-02 19:58:24 【问题描述】:

标记为作业,因为这是我在期中写的一个我不明白答案的问题。我被要求在以下语句中解释每个 const 的用途:

const char const * const GetName() const  return m_name; ;

那么,这些 const 的解释是什么?

【问题讨论】:

代码可能不同,因为您发布的内容不正确。很可能是class X const char * const getName() const return m_name; ... 等等,期中考试你写了吗? const char const 中的双常量在 C99 中有效,但在 C++ 中无效。只允许使用一个 const,但删除哪一个并不重要。 @对不起,错字。是的 const 在函数之前。我几个月前写的期中考试。 @tster:“写考试”是加拿大人(可能还有英国和其他几个国家)所说的美国人所说的“参加考试”。这对他们来说与“创建测试”的含义不同,所以 4501 并不是说​​他们创建了这个测试并且不理解问题。 【参考方案1】:

从右边拿走它们。 ; 之前的那个告诉客户这是一个设计级别的常量,即它不会改变对象的状态。 (将此视为只读方法。)

好的,现在返回值:

const char const *const

这是一个指向ok的常量指针……我们来吧!你有一个额外的const——一个语法错误。以下是等效的:const TT const。如果你取出const,你会得到一个指向常量字符的常量指针。这有帮助吗?

【讨论】:

澄清一下,您示例中的 T 是 char,而不是 char*。所以放在一起: const char *const 等价于 char const * const。 @4501:不。在符合标准的编译器中尝试一下。 它同时指向一个常量字符和常量字符S。差异仅与上下文相关,因为您可以通过索引该指针来获取内存中的任何地址。 “您可以通过索引该指针来获取内存中的任何地址”(a)无效,并且(b)实际上根本不是在分段内存架构上。 @dirkgently:如果没记错的话,GCC 会生成一个诊断信息,大意是“你想要 const 多少?”【参考方案2】:

您的 const 超出了语法允许的范围,该代码将无法编译。删除“char”之后和“*”之前的“const”。此外,最后一个 const 必须在函数体之前。从右到左阅读这样的内容会有所帮助。

const char * const GetName() const  return m_name; ;

你有一个 const 函数(即该函数不会改变类的状态。),它返回一个指向 const char 的 const 指针。

【讨论】:

最后一个const也要移到方法体之前,准确的说不能是函数,而是方法。 @dribeas,这是一个功能。 C++ 中不存在方法。 是的,关于主体,你是对的,但关于方法与函数语句的说法并不正确。 应该可以正常编译。你检查了吗? 期中题,指针前有一个const。【参考方案3】:

(1)const char (2)const * (3)const GetName() return m_name; (4)常量;

    char 数组的内容是 const。当您返回对象成员的指针时,这很好。由于您为第 3 方提供了指向您的成员的指针,因此您希望防止它被外部更改。 这种形式不经常使用,与(1)基本相同 我们指向 char 数组的指针是 const,因此您也不能更改指针指向的位置。 它限定了 GetName() 自身,这意味着该方法因此也不会更改它应用的类。因此只能为这种类型的 const 对象调用它。 这种形式通常用作 GetName(...) const。

正如另一个答案中已经提到的那样,“记住”它的技巧是从右到左阅读:

const T * - 指向 const T 的指针 T * const - 指向 T 的 const 指针

【讨论】:

不正确:(1) 和 (2) 是等价的。即const TT const 是相同的。另一方面T const *T * const是不同的,一个将T标记为常量,另一个将指针标记为常量。【参考方案4】:

编辑:看起来我错误地将代码粘贴到 Comeau 中,或者它在原始答案中被编辑为正确。无论哪种情况,我都会保留下面的答案,就好像代码不正确一样。

Comeau 在线编译器给出以下结果:

“ComeauTest.c”,第 4 行:错误:类型 多次指定限定符 const char const * const GetName() 返回 m_name; 常量; ^

“ComeauTest.c”,第 4 行:警告:类型 返回类型的限定符是 无意义的 const char const * const GetName() 返回 m_name; 常量; ^

“ComeauTest.c”,第 4 行:错误: 声明没有声明任何东西 const char const * const GetName() 返回 m_name; 常量;

这意味着您的语句格式不正确。

const char const * const GetName()  return m_name;  const;

第一个和第二个 const 的意思是一样的。您不能多次指定相同的限定符,因此必须删除其中一个才能编译代码。这两个 const 都指定 GetName 返回的指针所指向的值不能被修改,使得这样的代码无效:

const char* name = c.GetName();
name[0] = 'a';

第三个 const 指定 GetName() 返回的指针本身不能修改,但正如 Comeau 指出的那样,这对返回值没有任何作用,因为返回值是指针的副本而不是指针本身,并且可以分配给非常量指针。

第四个 const 放错了位置,它应该在 GetName 和函数体之间,如下所示:

const char* GetName() const  return m.name; 

此 const 指定在执行 GetName 期间不会修改类的任何成员。假设 GetName 是 Person 类的成员,则允许使用以下代码:

const Person& p;
p.GetName();

没有这个常量,上面的代码就会失败。

【讨论】:

+1 用于指出使返回的指针不可修改的无意义。 GCC 也会对此发出警告(如果您将警告视为错误,代码仍然无法编译 :))。了解这些 const 的含义很重要,但函数的返回类型似乎是一个相当不幸的演示选择。【参考方案5】:

您可能在第二个 const 关键字之前错过了“*”符号。

const char * const * const GetName() const  return m_name; ;

所以这意味着函数返回常量指针到常量指针到常量字符。

【讨论】:

【参考方案6】:

最后一个常量:

函数不会改变类的私有属性

最后一个常量:

它是一个常量指针(即它指向的place是常量)

第二个常数:

函数返回一个 const char(即 char 的内容是常量)

第一:

不知道?

所以要完整: 该函数将一个常量指针(始终相同的位置)返回到一个常量 char(始终相同的内容),并且该函数不会修改类的状态。

【讨论】:

一个 const 方法不能改变类的任何成员,也不能调用任何非 const 方法。 @quamrana:const 方法可以更改静态或可变的数据成员。 @Jerry:你是对的。让我重新表述一下:const 方法不能更改任何公共、受保护或私有成员,除非它们是静态或可变的。【参考方案7】:

const(1) char const(2) * const GetName() return m_name; 常量(3);

const char * const result = aaa.GetNAme();

3 - const 方法,不允许更改成员,也不允许调用任何非 const 方法。

1 - 不允许修改指针内部,即 *result = ..

2 - 不允许移动指针,即 result = NULL

【讨论】:

【参考方案8】:

给定:

const char const * const GetName() const  return m_name; ;

第一个和第二个 const 是等价的,但只允许其中一个 - 即您可以将 const 放在类型之前或之后(在本例中为 char),但只能放置一个或另一个,不能同时放置两者。但是,要么表示指针指向的字符不能被写入。

'*' 后面的const 表示函数返回的指针本身不能被修改。这在返回类型上很少见——您返回的是一个值,在任何情况下都不能修改(它通常只是分配给某个变量)。但是,这在其他情况下可能是有意义的。

第三个const 只允许在member 函数上使用。它说调用这个函数时,接收到的this指针将是T const * const而不是T * const,所以成员函数只能修改staticmutable对象的成员,如果它调用其他成员函数,它们也必须是const。然而,有一个警告,它也可以抛弃 const'ness,在这种情况下,它可以修改它认为合适的内容(进一步警告,如果对象最初定义为 const,而不仅仅是拥有const 指向普通(非常量)对象的指针,结果将是未定义的)。

【讨论】:

以上是关于const 正确性: const char const * const GetName const (//stuff);的主要内容,如果未能解决你的问题,请参考以下文章

const 正确性: const char const * const GetName const (//stuff);

将 Swift 字符串数组转换为 const char * const *

int main(int, char const* const*) 格式正确吗?

const char * char const * char * const 三者的区别

const char * char const * char * const 三者的区别

const char**与char**之间赋值问题