Chinaunix

标题: A::A::A(); [打印本页]

作者: 3040602024    时间: 2007-06-02 22:24
标题: A::A::A();
class A
{
        int j;
public:
        A(){cout<<"heo"<<endl;}
        ~A(){cout<<"endl\n";}
};

main()
{
        A::A::A();
        A aaaa();
}
都没调用构照函数。谁能说一下这是什么玩意啊。
作者: 3040602024    时间: 2007-06-02 22:53
我怎么一发贴都没人回啊
作者: antigloss    时间: 2007-06-02 22:55
A::A::A(); 这个不知道是什么。可以编译?
        A aaaa(); 这是一个函数原型。

少钻牛角尖,多看好书。
作者: MMMIX    时间: 2007-06-02 23:04
原帖由 3040602024 于 2007-6-2 22:53 发表
我怎么一发贴都没人回啊

估计是没有几个人知道你说的是什么玩意 :em12:
作者: ypxing    时间: 2007-06-02 23:36
原帖由 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();
}
都没调用构照函数。谁能说一下这是什 ...


A aaaa; 这是声明并定义一个A的对象,会调用构造函数
A aaaa();这是声明了一个函数aaaa, 它不需要参数,并返回A的一个对象
作者: 3040602024    时间: 2007-06-03 12:01
谢谢,
A::A();和A::A::A()
到底是什么啊。对一个简单、问题 深入理解不是钻牛角尖
你可能会了解你易想不到的收获
作者: antigloss    时间: 2007-06-03 12:03
原帖由 3040602024 于 2007-6-3 12:01 发表
谢谢,
A::A();和A::A::A()
到底是什么啊。对一个简单、问题 深入理解不是钻牛角尖
你可能会了解你易想不到的收获

我觉得理解这个没有任何收获。真的可以编译通过?不会有任何警告?
作者: epegasus    时间: 2007-06-03 12:23
原帖由 antigloss 于 2007-6-3 12:03 发表

我觉得理解这个没有任何收获。真的可以编译通过?不会有任何警告?



编译能通过,让我开眼了
作者: antigloss    时间: 2007-06-03 12:34
不知道lz哪里学来这种东西的。
作者: epegasus    时间: 2007-06-08 21:25
牛人来回答一下吧
作者: 飞灰橙    时间: 2007-06-08 21:57
不奇怪
  1. A::A::A::A::A::A::A::A::A::A::A::A::A();
复制代码

也可以编译通过
作者: whyglinux    时间: 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
复制代码

这已经写在标准草案中。至于能否成为正式的标准,还需拭目以待。
作者: tyc611    时间: 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
这已经写在标准草案中。至于能否成为正式的标准,还需拭目以待

不知道这样做有何意义? 让程序员更头痛点?
作者: flyingzhang    时间: 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 编辑 ]
作者: whyglinux    时间: 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 的临时对象。知道了这一点,一切都好解释了。
作者: flyingzhang    时间: 2007-06-21 11:19
呵呵 谢谢whyglinux兄
作者: pallas2k    时间: 2007-08-18 14:30
A::A::A()
还以为第一个A是namespace呢?原来还有这样的解释
不过这种解释越发头大了
还不如直接规定A::A() 就是构造函数,A::A:)非法呢




欢迎光临 Chinaunix (http://bbs.chinaunix.net/) Powered by Discuz! X3.2