- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
如果您尝试传递对临时对象的引用,则需要
const
:
这意味着在 C++ 中不可能将对象的可修改包装器建模为临时对象(无需强制使对象成为左值):
inline char * PcToUnix(AutoCStringBufferA & buffer) { return PcToUnix(buffer, buffer.size()); }
inline char * PcToUnix(CStringA & str) { return PcToUnix(make_autobuffer(str)); }
PcToUnix
:将字符缓冲区从 CR+LF 原位转换为 CR。make_autobuffer
:获取一个 CString
,并锁定其底层字符缓冲区,以便我们可以在 autobuffer
的生命周期内直接访问以对其进行操作。
所以我不能编写一个调用语句来获取底层字符串,将其包装在缓冲区管理对象(可变)中,将其传递给操作缓冲区内容的函数,然后返回,除非 autobuffer
声明为作为 const &
传递:
错误:
inline char * PcToUnix(AutoCStringBufferA & buffer) { return PcToUnix(buffer, buffer.size()); }
好吗?!
inline char * PcToUnix(const AutoCStringBufferA & buffer) { return PcToUnix(buffer, buffer.size()); }
但是“正确”的形式似乎指定了一个契约(Contract):“我不会修改你的缓冲区”。这里的 constness 在 autobuffer
对象级别在逻辑上是正确的 - 它在 PcToUnix() 期间没有被修改 - 缓冲区包装器对象本身(即 autobuffer
)在 PcToUnix
期间未修改 - 所以它确实是 const
...
但是,但是,它正在修改其底层对象 - 根据定义 - 其他东西的包装器 - 并且其他东西已被修改。
在我看来,这似乎是 C++ const
的一个根本缺陷。没有办法同时满足当前规则(不使用非标准编译器行为或编写误导性 API 契约(Contract)或编写不必要的冗长代码。
详细方法:
inline char * PcToUnix(CStringA & str) { auto adapter = make_autobuffer(str); return PcToUnix(adapter); }
误导性的 API 方法:
inline char * PcToUnix(const AutoCStringBufferA & buffer) { return PcToUnix(buffer, buffer.size()); }
inline char * PcToUnix(CStringA & str) { return PcToUnix(make_autobuffer(str)); }
如果 C++ 提供了一种方法来指定包装器的常量性与被包装对象的常量性分开,那么我们就有了一种合理的方法来创建规则并简洁地表达 API。但我只是不知道如何实现这一目标。
预智能指针(或对于没有包装层的所有上下文)可以从底层对象的常量中单独指定指针的常量:
T * const pConstPointerToMutableObject;
const T * pMutablePointerToConstObject;
const T * const pConstPointerToConstObject;
但是对于包装器对象没有任何相应的支持。没有办法将 referer 的常量与 refere 的常量分开表达。也没有任何一套合理的规则来定义或控制 const
的交换/关联/分配性质。
我不明白为什么没有经常提出这个问题。我经常偶然发现这一点,并发现 const
是一个巨大的 PIA,因为它 .
理想情况下,代码应该是简单可堆肥的——即一个人应该能够在另一层包装一些更简单的对象,以某种方式适应它——可能过滤访问,或者添加关于管理子对象的智能,或者底层事物的延迟实例化,等等,这样就可以建立复杂和特定的数据接口(interface),而不必一遍又一遍地重新设计基本对象——只需包裹在一两层中,为上下文添加必要的智能/逻辑/接口(interface)/适应这是需要的。
但由于常量正确性问题,C++ 使这几乎不可能。 (或者,我太愚蠢了,无法弄清楚如何做所有这些,并且在我广泛的阅读中,我已经设法想念它是如何完成的,甚至没有人在讨论这些问题而只是掩盖并忽略 const
的这一方面)。也许 SO 上的某个人可以纠正我的错误,无论我犯了什么错误??
最佳答案
const 正确性的简单方法:使用可传递的 const。
看来您对免费语言级别的要求有点过分了。实际上,它的设计(除其他事项外)是为了让您为使用的东西付费,并确保安全和高效。是的,它可能非常冗长。
就物理常量感知的容器而言,C++ 当然能够支持这种区别;例如:
void A(const std::shared_ptr<const bool>& p) { /* ... */}
void B(const std::shared_ptr<bool>& p) { /* ... */}
void C() {
A(std::make_shared<bool>(false)); // << ok
A(std::make_shared<const bool>(false)); // << ok
B(std::make_shared<bool>(false)); // << ok
B(std::make_shared<const bool>(false)); // << error. API forbids removal of const.
}
但 C++ 标准库并未提供您可能需要的所有容器来完成您的要求。
列举您需要的智能指针变体,并考虑它们负责对象的生命周期和从一个容器到另一个容器的转换。另请注意,如果您仅支持传递常量,该列表会缩短多少。然后考虑 OP 中的 API 通常会转换为模板以轻松支持变体。
有时,您必须处理接口(interface)不太理想的类型。在这些情况下,为它们创建一个容器并引入您理想的 const 形式通常是最简单的。
使用这种方法,容器完成了大部分繁重的工作(=让您免于在调用站点的冗长)。
当然,进行字符串转换的 C++ 风格看起来更像是:
std::string PCToUnix(std::string pString) {
...mutate pString...
return pString;
}
或就地:
void PCToUnix(std::string& pString) {
...mutate pString...
}
关于c++ - 如何正确组合可变对象 const,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27066943/
我的一位教授给了我们一些考试练习题,其中一个问题类似于下面(伪代码): a.setColor(blue); b.setColor(red); a = b; b.setColor(purple); b
我似乎经常使用这个测试 if( object && object !== "null" && object !== "undefined" ){ doSomething(); } 在对象上,我
C# Object/object 是值类型还是引用类型? 我检查过它们可以保留引用,但是这个引用不能用于更改对象。 using System; class MyClass { public s
我在通过 AJAX 发送 json 时遇到问题。 var data = [{"name": "Will", "surname": "Smith", "age": "40"},{"name": "Wil
当我尝试访问我的 View 中的对象 {{result}} 时(我从 Express js 服务器发送该对象),它只显示 [object][object]有谁知道如何获取 JSON 格式的值吗? 这是
我有不同类型的数据(可能是字符串、整数......)。这是一个简单的例子: public static void main(String[] args) { before("one"); }
嗨,我是 json 和 javascript 的新手。 我在这个网站找到了使用json数据作为表格的方法。 我很好奇为什么当我尝试使用 json 数据作为表时,我得到 [Object,Object]
已关闭。此问题需要 debugging details 。目前不接受答案。 编辑问题以包含 desired behavior, a specific problem or error, and the
我听别人说 null == object 比 object == null check 例如: void m1(Object obj ) { if(null == obj) // Is thi
Match 对象 提供了对正则表达式匹配的只读属性的访问。 说明 Match 对象只能通过 RegExp 对象的 Execute 方法来创建,该方法实际上返回了 Match 对象的集合。所有的
Class 对象 使用 Class 语句创建的对象。提供了对类的各种事件的访问。 说明 不允许显式地将一个变量声明为 Class 类型。在 VBScript 的上下文中,“类对象”一词指的是用
Folder 对象 提供对文件夹所有属性的访问。 说明 以下代码举例说明如何获得 Folder 对象并查看它的属性: Function ShowDateCreated(f
File 对象 提供对文件的所有属性的访问。 说明 以下代码举例说明如何获得一个 File 对象并查看它的属性: Function ShowDateCreated(fil
Drive 对象 提供对磁盘驱动器或网络共享的属性的访问。 说明 以下代码举例说明如何使用 Drive 对象访问驱动器的属性: Function ShowFreeSpac
FileSystemObject 对象 提供对计算机文件系统的访问。 说明 以下代码举例说明如何使用 FileSystemObject 对象返回一个 TextStream 对象,此对象可以被读
我是 javascript OOP 的新手,我认为这是一个相对基本的问题,但我无法通过搜索网络找到任何帮助。我是否遗漏了什么,或者我只是以错误的方式解决了这个问题? 这是我的示例代码: functio
我可以很容易地创造出很多不同的对象。例如像这样: var myObject = { myFunction: function () { return ""; } };
function Person(fname, lname) { this.fname = fname, this.lname = lname, this.getName = function()
任何人都可以向我解释为什么下面的代码给出 (object, Object) 吗? (console.log(dope) 给出了它应该的内容,但在 JSON.stringify 和 JSON.parse
我正在尝试完成散点图 exercise来自免费代码营。然而,我现在只自己学习了 d3 几个小时,在遵循 lynda.com 的教程后,我一直在尝试确定如何在工具提示中显示特定数据。 This code
我是一名优秀的程序员,十分优秀!