繁体   English   中英

typedef别名的析构函数

[英]Destructor of typedef alias

#include <iostream>

struct A { ~A(); };
A::~A() {
    std::cout << "Destructor was called!" << std::endl;
}

typedef A AB;
int main() {
    AB x;
    x.AB::~AB(); // Why does this work?
    x.AB::~A();
}

上述程序的输出是:

Destructor was called!
Destructor was called!
Destructor was called!

我假设前两行属于用户析构函数调用,而第三行是由于在退出main函数范围时调用析构函数。

根据我的理解,typedef是类型的别名。 在这种情况下, ABA的别名。

为什么这也适用于析构函数的名称? 非常感谢对语言规范的引用。

编辑:这是在macOS High Sierra版本10.13.3上使用Apple LLVM版本9.1.0(clang-902.0.39.1)编译的。

为什么这也适用于析构函数的名称?

因为标准说:

[class.dtor]

在显式的析构函数调用中,析构函数由〜后跟一个type-name或decltype-specifier来指定,该类型名称或decltype-specifier表示析构函数的类类型。 ...

typedef别名是一个类型名称,它表示与类本身的类型名称相同的类。

该规则甚至有一个澄清的例子:

 struct B { virtual ~B() { } }; struct D : B { ~D() { } }; D D_object; typedef B B_alias; B* B_ptr = &D_object; void f() { D_object.B::~B(); // calls B's destructor B_ptr->~B(); // calls D's destructor B_ptr->~B_alias(); // calls D's destructor B_ptr->B_alias::~B(); // calls B's destructor B_ptr->B_alias::~B_alias(); // calls B's destructor } 

有关名称查找的进一步说明,还有一个适用于该问题的示例:

[basic.lookup.qual]

如果伪析构函数名称([expr.pseudo])包含嵌套名称说明符,则类型名称将在nested-name-specifier指定的作用域中作为类型查找。 同样,在表单的qualified-id中:

nested-name-specifieropt class-name :: ~class-name

第二个类名在与第一个类相同的范围内查找。 [例如:

 struct C { typedef int I; }; typedef int I1, I2; extern int* p; extern int* q; p->C::I::~I(); // I is looked up in the scope of C q->I1::~I2(); // I2 is looked up in the scope of the postfix-expression struct A { ~A(); }; typedef A AB; int main() { AB* p; p->AB::~AB(); // explicitly calls the destructor for A } 

- 结束例子]

因为当您编写~AB()您没有命名或调用析构函数。 你写~后跟类 名称,析构函数调用自动配置为写彼此相邻的令牌的指定语义的结果。

通常这是学术性的,但在这里你明白为什么它很重要。

类似地,通过编写AB()您不是“调用构造函数”,即使这看起来像函数调用,并且许多语言新手以这种方式解释代码。 (当试图在没有参数推断的情况下调用模板构造函数时,这可以带来乐趣和游戏:如果不能命名构造函数,则无法提供这些参数!)

实际上,构造函数和析构函数在技术上没有名称!

这些细微差别让C ++变得有趣,对吗?

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM