像自定义类一样构造的指针(内置类型)如何工作?

Posted

技术标签:

【中文标题】像自定义类一样构造的指针(内置类型)如何工作?【英文标题】:How does a pointer (built-in types) which gets constructed like a custom class work? 【发布时间】:2019-12-11 13:00:56 【问题描述】:

我已经更改了问题的标题和正文,看看是否更适合:)。


我在cppreference: unique_ptr/reset 上阅读了成员函数签名。

void reset( pointer ptr = pointer() ) noexcept;

pointerunique_ptr的成员类型,documented为

pointer | std::remove_reference<Deleter>::type::pointer 如果该类型存在,否则 T*。必须满足NullablePointer

我在 cmets 中学到了什么:

    pointer ptr = pointer() 在某种程度上等同于例如int, using pointer = int*; pointer ptr = pointer() 如果它是像int 这样的内置类型,那么ptr 是一个零初始化 变量。我在这里得到一个带有0/NULL/nullptrint* 指针。 using pointer = int*; pointer ptr = pointer() 没有“原始”声明,即 int* ptr = int*() 不起作用。

我还阅读了Do built-in types have default constructors? ,这很有帮助。


我想了解更多关于这种行为的信息(可以以自定义类的方式构造内置类型),如果可以更详细地解释的话:

using pointer = int*; pointer ptr = pointer()

这个语句真的没有“原始”语法吗?我曾经认为所有使用typedefusing 的东西都可以用“原始”版本写下来。就像一对一的映射。

【问题讨论】:

期待空指针。 @Evg 为什么?如何? ... 问答 这能回答你的问题吗? What is the default constructor for C++ pointer? @Evg:该声明(部分原因可能是其年代久远)混淆了默认初始化和值初始化,T() 就是这样做的。 @Evg: (int*) 是复合文字;那些存在于 C 但不存在于 C++ 中。 【参考方案1】:

不需要你所说的“原始”语法,因为指针可以用 0 初始化为零。

int *p = 0; // nullptr

我猜它可能对模板参数推导有用,但我们已经有了一个语法:(int*)0。确实没有必要为这样的小东西添加更多语法(或者可能有人忘记添加它;但不管怎样,现在都没有必要了)。

T(...) 语法主要用于初始化用户定义类型的对象。

我曾经认为所有使用typedefusing 的东西都可以用“原始”版本写下来。

这是另一个例子:

int a;
a.~int(); // syntax error

using Int = int;
a.~Int(); // ok!

第一个语句是不允许的,因为它是空操作。第二个不是因为在通用上下文中它可能会做某事(破坏对象)而不是无操作。由于语言不想不必要地限制这一点,因此允许通过别名。

出于同样的原因,即使您无法写出语法,pointer() 也被允许:如果它被禁止,那么在通用上下文中工作会很痛苦。

【讨论】:

说得很好。聊天室的一位朋友也提到了“通用”部分。 chat.***.com/transcript/message/48085012#48085012 你说“我们已经有(int*)0”是什么意思?对不起,我不太记得模板部分。我刚刚在我的机器上测试过。我只能使用 (int*)0 来初始化像 int, int* 这样的内置类型,但不能用于自定义类类型。 (T)0 似乎不是using pointer = int*; pointer ptr = pointer() 的替代品。 另一个问题:“第一个语句是不允许的,因为它是无操作的。”。所以no-p == not allowed?我对no-op 概念及其与语言的交互方式知之甚少。 @Rick (T)0 是的,只是内置类型。这是一个无操作,因此允许它会产生误导,因为它不做任何事情

以上是关于像自定义类一样构造的指针(内置类型)如何工作?的主要内容,如果未能解决你的问题,请参考以下文章

C++ 中的三种类型

类拓展——拷贝控制成员

如何判断变量是指针/构造函数抛异常

类(对象)的定义 自定义对象构造函数

默认构造函数是不是初始化内置类型?

如何使用Predicate以及如何自定定义Predicate委托