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兄
|