为什么我可以更改此const NSMutableSring?

时间:2014-04-02 13:44:41

标签: objective-c cocoa-touch cocoa const

我有这个示例代码:

const NSMutableString *const foobar = [[NSMutableString alloc] initWithFormat:@"Hello"];
[foobar appendString:@" World"];
NSLog(@"String: %@", foobar);

并输出:

  

字符串:Hello World

我的变量不应该是const(以及指针)吗?因此我不能修改它。

C ++的行为与我期望的一样

int main() {
    const std::string *const s = new std::string("hello");
    s->append(" world");
    std::cout << s << std::endl;
}

输出:

$ g++ test.c++
test.c++: In function ‘int main()’:
test.c++:7:20: error: passing ‘const string {aka const std::basic_string<char>}’ as ‘this’ argument of ‘std::basic_string<_CharT, _Traits, _Alloc>& std::basic_string<_CharT, _Traits, _Alloc>::append(const _CharT*) [with _CharT = char; _Traits = std::char_traits<char>; _Alloc = std::allocator<char>]’ discards qualifiers [-fpermissive]
  s->append(" world");

我知道我不应该将const与mutable一起使用,但这不会改变事实,即mutable应该是const

3 个答案:

答案 0 :(得分:2)

我怀疑它是这样的:&#34; const NSMutableString * const foobar&#34;导致两件事情变得不变:对象的ptr和对象本身。但是,我敢打赌,对象本身只是一个指针结构,而且这些指针不是常量。

在c ++中,你创建不可变的方法是将它声明为const,在Objective-C中你选择常规版本,默认情况下通常是不可变的。

答案 1 :(得分:2)

您的观察是正确的,在 T 的情况下,指向常量T 的指针静默地更改为指向T 的指针一个Objective-C类。

这在技术上不是偏离C(++)中const的语义,因为C(++)中没有Objective-C类类型,因此它们不被C覆盖( ++)标准。

Objective-C本身没有任何形式的描述,足够好的标准。 Objective-C 2.0编程语言,2009,没有提到常量语义,也很久以来作为参考被遗弃并且没有被替换。

换句话说,我无法指导您查看任何明确的文档,该文档指出const默默地省略了Objective-C类类型,但这就是编译器的行为方式。

如果你想要“常量”对象,你必须遵循Objective-C可变/不可变类模式。

答案 2 :(得分:-1)

const表示指针的地址是常量,因此您可以更改/附加字符串。最佳做法是,始终使用const NSString。希望这会有所帮助。