首页 > 学技术 > 技术网文 > C/C++ > 正文

[精彩] A::A::A();


来源 chinaunix.net kuqin整理

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:06

我怎么一发贴都没人回啊


 antigloss 回复于:2007-06-02 22:55:08

A::A::A(); 这个不知道是什么。可以编译?
        A aaaa(); 这是一个函数原型。

少钻牛角尖,多看好书。


 MMMIX 回复于:2007-06-02 23:04:05

引用:原帖由 3040602024 于 2007-6-2 22:53 发表
我怎么一发贴都没人回啊 


估计是没有几个人知道你说的是什么玩意 :em12:


 ypxing 回复于:2007-06-02 23:36:33

引用:原帖由 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:34

谢谢,
A::A();和A::A::A()
到底是什么啊。对一个简单、问题 深入理解不是钻牛角尖
你可能会了解你易想不到的收获


 antigloss 回复于:2007-06-03 12:03:58

引用:原帖由 3040602024 于 2007-6-3 12:01 发表
谢谢,
A::A();和A::A::A()
到底是什么啊。对一个简单、问题 深入理解不是钻牛角尖
你可能会了解你易想不到的收获 


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


 epegasus 回复于:2007-06-03 12:23:21

引用:原帖由 antigloss 于 2007-6-3 12:03 发表

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




编译能通过,让我开眼了:em21:


 antigloss 回复于:2007-06-03 12:34:46

不知道lz哪里学来这种东西的。


 epegasus 回复于:2007-06-08 21:25:56

牛人来回答一下吧


 飞灰橙 回复于:2007-06-08 21:57:57

不奇怪
 A::A::A::A::A::A::A::A::A::A::A::A::A(); 

也可以编译通过


 whyglinux 回复于:2007-06-12 22:46:35

引用:原帖由 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 类的 [color=blue]构造函数成员[/color],而不是类本身,即 class-name::class-name 不是一个 [color=blue]类型[/color]。

假设 A 是一个类名,对 A::A 的使用情况作进一步的说明。如上所言,A::A 是类 A 的构造函数,不是类型。下面在类定义外面的使用情况都应该是非法的;
A::A a;         // error, A::A is not a type name.

struct A::A a2; // error, A::A is not a type name.
A::A::A a1;     // error, A::A is not a type name.
                // The left operand of the second :: operator is A::A, and
                // it should be a class or namespace name, but it is not.
A::A func();    // error, A::A is not a type name.
A::A();         // error, redeclaration of a member function is not allowed.
&A::A;          // error, constructors (and destructors) have no address.
A a;
a.A::A();       // error, constructor cannot be called explicitly.

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

  // ...
}

这也从一个侧面告诉我们:在类定义中声明(包括定义)的构造函数不应该在前面再加上类名来修饰:
struct A {

  A(); // ok, A is an unqualified declarator-id.
  // A::A(); will be an error, since all members of class A
       // declared in class A definition cannot be qualified.
};

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

因此,目前已经有人提案,建议 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

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


 tyc611 回复于:2007-06-12 23:21:26

引用:
因此,目前已经有人提案,建议 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:12

通过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:44

>> 在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:33

呵呵 谢谢whyglinux兄




原文链接:http://bbs.chinaunix.net/viewthread.php?tid=944102
转载请注明作者名及原文出处



收藏本页到: