相关:“将'const NSString *'发送到类型'NSString *'的参数将丢弃限定符”警告
有时候,我认为这很有用。我可能需要传递一个表,并要确保该表的内容不会更改。
但是,在大多数Objective-C程序示例中,我从未见过const
。我的问题是为什么?
相关:“将'const NSString *'发送到类型'NSString *'的参数将丢弃限定符”警告
有时候,我认为这很有用。我可能需要传递一个表,并要确保该表的内容不会更改。
但是,在大多数Objective-C程序示例中,我从未见过const
。我的问题是为什么?
Answers:
由于Objective-C对象的工作方式,const
它放弃了强制执行并开始成为程序员的一种表示法。考虑以下程序:
int f(const int x) {
return ++x;
}
int main(int argc, char *argv[]) {
@autoreleasepool {
int x = 3;
NSLog(@"%d", f(x));
}
return 0;
}
这实际上不会在这里编译(我正在使用clang):编译器可以检测到尝试修改原始C类型的尝试并发出错误。但是现在将其与该程序进行比较:
NSMutableString *f2(const NSMutableString * const x) {
[x appendString: @" world!"];
return x;
}
int main(int argc, char *argv[]) {
@autoreleasepool {
NSMutableString *x = [@"Hello" mutableCopy];
NSLog(@"%@", f2(x));
}
return 0;
}
即使向函数传递了指向常量对象的常量指针,也仍然可以对对象进行突变。
在面向对象的编程中,增强对象恒定性的最佳方法是使该对象不可变-即,不提供任何可以更改其状态的方法。想象一下,上面的函数接受了一个NSString
参数而不是NSMutableString
,并且我传递了文字@"Hello"
而不是可变的副本。合理地说,现在没有机会使传入的对象[*]发生变异。Objective-C中并没有强制执行,虽然,不同于任何方式const
或final
其他面向对象语言的对象引用。
为了进行比较,const
在C ++中的工作方式完全不同。如果获得const
对C ++对象的引用,则只能const
在该对象上调用成员函数。这些函数const
通过不进行任何更改或仅修改已由mutable
类设计器明确标记的成员变量来保留对象的-ness 。因此,想象一下我MutableString
在C ++中有某种类型,与NSMutableString
Objective-C中的类型相同。我上面的示例的等效内容如下所示:
MutableString& f3(const MutableString& x) {
x.appendString(" world!");
return x;
}
这绝对不会编译:除了appendString()
不是const
操作外,该函数还会const
从需要使用的类型引用中删除限定符const_cast
。
[*]我期望有一种扭曲的方法,但是现在我们进入了一个程序员试图通过做“聪明”的事情来破坏另一个人的领域。
const
在目标C中声明某个对象的指针永远不会分配为指向另一个对象可能仍然有用。也就是说,NSString * const x
您知道这x
将始终是相同的字符串,而不是不同的字符串。
就Objective C而言,我没有编程,所以无法回答这个问题。我可以回答的问题是“人们在使用const
Objective C进行编程时会使用很多吗?” -那是肯定的“是”。
常量本质上是一种软件安全性功能,用于使程序更可靠和可维护。许多程序员在成长过程中并没有真正意识到const
s 的值,直到有一天发生了一些不好的事情,他们才有了“啊哈”的时刻-“哦,那const
是用来干的”。完全可以编写没有常量的程序,几乎不可能使该程序可靠。
许多代码示例并不是真正的程序,仅仅是旨在显示特定功能的代码片段。他们不使用const
样本,因为这会分散样本的意图。您看到的另一种类型的代码是由经验不足的程序员编写的代码,这些程序员根据所学的示例或了解常数的示例来执行工作,并且懒于使用它们。