免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12
最近访问板块 发新帖
楼主: 3040602024
打印 上一主题 下一主题

A::A::A(); [复制链接]

论坛徽章:
0
11 [报告]
发表于 2007-06-08 21:57 |只看该作者
不奇怪
  1. A::A::A::A::A::A::A::A::A::A::A::A::A();
复制代码

也可以编译通过

论坛徽章:
0
12 [报告]
发表于 2007-06-12 22:46 |只看该作者
原帖由 3040602024 于 2007-6-2 22:24 发表
class A
{
        int j;
public:
        A(){cout<<"heo"<<endl;}
        ~A(){cout<<"endl\n";}
};

main()
{
        A::A::A();
        A aaaa();
}
都没调用构照函数。谁能说一下这是什 ...


楼主的程序涉及到 C++ 中的两大重要内容--名字查找(Name lookup)以及歧义解析(Ambiguity resolution),都是很迷惑人的东西。

其中的歧义解析(即关于 A aaaa(); 的问题)详见下面这个帖子中我的解释:
http://bbs.chinaunix.net/viewthread.php?tid=847260

在这里主要说明 A::A 的含义以及诸如 A::A::A 这样二重以上的限定非法的问题。

根据目前 C++ 标准(1998版 和 2003版)的规定,如果 class-name::class-name 中的 class-name 指的是同一个类名,则这种形式表示的是 class-name 类的 构造函数成员,而不是类本身,即 class-name::class-name 不是一个 类型

假设 A 是一个类名,对 A::A 的使用情况作进一步的说明。如上所言,A::A 是类 A 的构造函数,不是类型。下面在类定义外面的使用情况都应该是非法的;
  1. A::A a;         // error, A::A is not a type name.
  2. struct A::A a2; // error, A::A is not a type name.
  3. A::A::A a1;     // error, A::A is not a type name.
  4.                 // The left operand of the second :: operator is A::A, and
  5.                 // it should be a class or namespace name, but it is not.
  6. A::A func();    // error, A::A is not a type name.
  7. A::A();         // error, redeclaration of a member function is not allowed.
  8. &A::A;          // error, constructors (and destructors) have no address.
  9. A a;
  10. a.A::A();       // error, constructor cannot be called explicitly.
复制代码

根据现行标准,A::A 能够合法使用的唯一场所是在位于类定义之外的构造函数的定义中:
  1. A::A() { // ok, A::A donates the constructor.
  2.   // ...
  3. }
复制代码

这也从一个侧面告诉我们:在类定义中声明(包括定义)的构造函数不应该在前面再加上类名来修饰:
  1. struct A {
  2.   A(); // ok, A is an unqualified declarator-id.
  3.   // A::A(); will be an error, since all members of class A
  4.        // declared in class A definition cannot be qualified.
  5. };
复制代码

然而有的编译器允许使用诸如 A::A::A::A 这样的多重修饰,是因为把 A::A 作为类型来处理的,特别是在有明确类型语义要求的上下文环境中。虽然与标准不符,但是这样做有一定的道理。

因此,目前已经有人提案,建议 A::A 不单独作为构造函数解释,而是在一些只能作类型解释的语义环境下使其成为类型 A。比如下面的情况:
  1. A::A a;         // error, A::A is not a type name.
  2. struct A::A a2; // ok, a2 is an object of type A
复制代码

这已经写在标准草案中。至于能否成为正式的标准,还需拭目以待。

评分

参与人数 1可用积分 +3 收起 理由
langue + 3 精品文章

查看全部评分

论坛徽章:
0
13 [报告]
发表于 2007-06-12 23:21 |只看该作者
因此,目前已经有人提案,建议 A::A 不单独作为构造函数解释,而是在一些只能作类型解释的语义环境下使其成为类型 A。比如下面的情况:

A::A a;         // error, A::A is not a type name.
struct A::A a2; // ok, a2 is an object of type A
这已经写在标准草案中。至于能否成为正式的标准,还需拭目以待

不知道这样做有何意义? 让程序员更头痛点?

论坛徽章:
0
14 [报告]
发表于 2007-06-19 15:26 |只看该作者

回复 1楼 3040602024 的帖子

通过gcc4.1/3.4的测试,A的构造函数是被调用过了的。 但在VC6上测试, 确认没有调用过A的构造函数M(事实上通过反汇编可以看到生成的可执行文件什么事情也没有做)。

在GCC上,A::A::A();一句调用过了A::A()以后立即调用了A::~A() 不知道作何解释?whyglinux 的回答中似乎也不能给出一个解释。

在VS2005上面,这一句直接被报出了语法错误: error C3083: '{ctor}': the symbol to the left of a '::' must b
e a type

[ 本帖最后由 flyingzhang 于 2007-6-19 15:33 编辑 ]

论坛徽章:
0
15 [报告]
发表于 2007-06-20 16:31 |只看该作者
>> 在GCC上,A::A::A();一句调用过了A::A()以后立即调用了A::~A() 不知道作何解释?

上面已经说过,这就是把 A::A 看作类型的情况(非标准行为)。A::A 表示在 A 中搜索名字 A,其结果仍然指的是 同一类型的 A;同样,A::A::A 也还是 A,所以 A::A::A() 等同于 A()。如果 A 是一个非函数类型,则 A() 表示建立一个类型为 A 的临时对象。知道了这一点,一切都好解释了。

论坛徽章:
0
16 [报告]
发表于 2007-06-21 11:19 |只看该作者
呵呵 谢谢whyglinux兄

论坛徽章:
0
17 [报告]
发表于 2007-08-18 14:30 |只看该作者
A::A::A()
还以为第一个A是namespace呢?原来还有这样的解释
不过这种解释越发头大了
还不如直接规定A::A() 就是构造函数,A::A:)非法呢
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP