在C++中,析构函数是否应该使用指针声明?

8
在 C++0x -n3290 草案中,他们在析构函数章节的第 12.4/2 点的最后一行添加了内容。
          **A destructor shall not be declared with a ref-qualifier.**

在c++03草案中……他们在析构函数中没有提到这一点吗?

我的问题是是否

   *~S() ;   //this declaration is allowed or not according to the Standard's
   //**~S(); ***~S() ; etc...........

这种声明是允许的吗? 在草案中没有描述这个声明...

在GCC 4.6.0,Sun/Oracle C++12.0中,这种声明是被允许的。 但在Comeau C/C++中是不被允许的。

3个回答

10

我觉得这个函数声明看起来不像是合法的,特别是作为一个析构函数。我不确定标准中的这部分是在讲什么,但我有一个猜测。

我猜可能有一个限定符说你的函数被调用时是在一个右值引用上。类似于这样:

class A {
 public:
   void IAmAnRValue() &&;
};

我认为标准中的语言表明,这个限定符不能用于析构函数,就像有一个尾随的const也是不合法的。

进一步调查后,我对我的推测的正确性更加确定了。以下是理由:

在那里,它清楚地说明函数现在可以在“cv-qualifer”之后具有“ref-qualifier”。这意味着函数声明现在可以跟随const&const volatile&&而不仅仅是const。而且使用的术语(ref-qualifier)与您引用的标准中使用的术语相同。对于析构函数不能有一个这样的限定符是有道理的。


7

您对新标准中的ref-qualifier的含义存在误解。与您可以在C++03中为任何成员函数提供const限定符一样,您也可以在C++0x中向成员函数添加ref-qualifier。该修饰符将影响函数的隐式this参数的类型:

struct test {
   void f() const &&;  // implicit "this" in "f" is of type "test const &&"
};

与C++03标准不同,析构函数在C++0x中不能是static、const或const volatile类型,并且也不能采用引用限定符(&或&&)。当然,在C++03标准中不存在这一点。

@David:哦...但是关于析构函数的声明,他们只提到了 ~ 运算符,但是没有说过这样的声明是否允许、不允许等等...比如 *A(),&A() 等。 - user751747
2
语法规定ref-qualifier附加到函数的最右侧(在cv-qualifiers之后),这意味着该句子指的是:~A() &;~A() &&;,并将两者都定义为无效。&~A();*~A();无效,因为它们不符合grammar,没有必要对所有不应编译的内容提供额外的描述。例如,在标准中没有说a][+=/a是不正确的,它只说明了哪些结构是正确的,而这个例子不符合任何一个。 - David Rodríguez - dribeas
@David,我认为*~A()&~A()都是不正确的语法。应该有一些规则使它们无效。我还没有检查过这个规则... - Johannes Schaub - litb
@litb:在语法中允许的位置是哪里?我从member-specification开始(假设声明析构函数的上下文是成员声明符),但我没有找到任何允许member-specification*开头的地方。你是怎么做到的? - David Rodríguez - dribeas
@litb:我在编译期间花了一些时间来审查语法,我没有看到任何反驳这个说法的东西,但我只是想知道这有什么意义,因为语法中的 declarator 基本上声明 * a; 是一个有效的成员声明(仅根据语法),这似乎表明在这种情况下语法过于灵活存在问题。 - David Rodríguez - dribeas
显示剩余2条评论

1

你要找的规则在同一段落中,12.4p2

析构函数不带参数,也不能为其指定返回类型(甚至不是void)。

短语“不能为其指定返回类型”也禁止使用“*”,这一点不是立即清楚的,但可以通过与12.3.2p1进行比较(与this issue report进行比较)来看到:

... 这种函数称为转换函数。不能指定返回类型。

这个规则是导致实现禁止* operator int() { }的原因。你也可以引用12.4p1,虽然由于其表述非常普遍且是析构函数部分的第一条语句,我认为上面的其他语句应该是主要论据。

在类定义中,使用一个可选的函数说明符(7.1.2),后跟˜,后跟析构函数的类名,后跟空参数列表的特殊声明语法用于声明析构函数。

正如可以看到/阅读的那样,在该描述中没有提到诸如*之类的声明符号,这显示了作者的意图。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接