c++ 临时给指针赋一个任意值

af7jpaap  于 2023-07-01  发布在  其他
关注(0)|答案(3)|浏览(107)

假设我定义了一个指向任何类型的指针:A* p .我想以后再赋值,但只在我最初知道的条件下赋值。

布尔型的基本解决方案

A* p;
bool assign_p = condition; // initially
p = assign_p ? new A : NULL; // later

然而,为了保存空间,我想避免使用额外的变量(布尔值),因为这个过程发生在大型数组上。我的问题是:我可以使用指针作为临时布尔值吗?

任意指针值的解决方案?

A *p = condition ? (A*) 1 : NULL; // initially
A *p = p ? new A : NULL; // later

这只使用了一个变量(指针),但是即使它没有指向任何地方,也分配(A*) 1是安全和良好的做法吗?

有工会的解决方案?

union boolA { bool assign; A* p; };
boolA P = {condition}; // initially
P.p = P.assign ? new A : NULL; // later

这也应该只使用指针所需的内存,本质上与上面的解决方案相同,也许是更好的方式?但我对工会发生的未定义行为有点困惑。在这方面安全吗?此外,如果我需要有许多这样的指针,那么制作联合数组是一个好的实践吗?

其他解决方案?

pkln4tw6

pkln4tw61#

这可以通过使用 sentinel(以特殊方式解释的实际值,类似于数字-1通常用于指示搜索函数中的“未找到”)以安全的方式解决。创建一个A示例(将其成员设置为任意但安全的值,例如所有零和空值),将其存储为A * sentinel,并将“true”数组元素设置为sentinel。当你准备好分配真实的对象时,你可以将数组元素与sentinel进行比较。

kfgdxczn

kfgdxczn2#

许多系统都没有实际的指针,其值低于某个截止值(例如0x10000),因此您可以以完全不同的方式处理高于和低于该截止值的值。
一个例子是windows,其中低于截止值的值将被许多与窗口相关的函数视为资源值,而高于截止值的值将被视为字符串指针(char或wchar_t,取决于被调用的函数)。
我认为一个以完全不同的方式处理0、1和0x10000以上的值的函数没有问题。

du7egjpx

du7egjpx3#

前面提出的sentinel是一个很好的解决方案,但是如果你很难为你的对象A找到这样的值,我认为std::optional<A*>也可能是一个很好的解决方案。你可以有三种状态-

  • std::nullopt-尚未初始化可选
  • *opt = nullptr-已经初始化了可选的,但是使用了nullptr(因为不满足条件)
  • *opt = a-已使用正确的值初始化可选值(满足条件)。

我认为主要的优点是前两个选项具有不同的状态,这对于您将来可能需要的进一步逻辑以及调试目的可能非常有用。它也比sentinel更干净,因为未来的读者/开发人员在每次使用时都不需要记住“跟踪”检查的“特殊值”。
如果std::optional对你来说很“重”,因为你在数组中有很多元素,你也可以使用A**,并模拟三种情况(ptr = nullptr*ptr = nullptr**ptr = a)。

相关问题