2012-03-12 153 views
0

这里是我的代码:类类型转换:为什么类型转换功能不叫

1  #include <cstdio> 
    2 
    3  struct Foo; 
    4 
    5  struct Bar { 
    6   Foo *foo; 
    7   Bar(const Foo& fo) { 
    8    printf("In Bar copy_contr\n"); 
    9   } 
10 
11   Bar& operator=(Foo& fo) { 
12    printf("In Bar assignment\n"); 
13    this->foo = &fo; 
14   } 
15  }; 
16 
17  struct Foo { 
18   Bar *bar; 
19   Foo() { 
20    printf("In default\n"); 
21   } 
22 
23   Foo(const Bar& b) { 
24    printf("In Foo copy constructor\n"); 
25   } 
26 
27   operator Bar() { 
28    printf("In typecast from Foo to Bar\n"); 
29    return *(this->bar); 
30   } 
31 
32  }; 
33 
34 
35  int f(Bar b) { 
36   return 0; 
37  } 
38 
39  int main() { 
40   Foo fo; 
41   f(fo); 
42   Bar *b = &static_cast<Bar>(fo); 
43 
44   return 0; 
45  } 

这里是打印出来:我在第三打印混淆

In default 
In typecast from Foo to Bar 
In Bar copy_contr 

:如何来复制构造函数被调用,它应该是类型转换,在那里有特定的static_cast。

我也有一个有趣的发现 - 如果我注释掉line27 - line30,基本上使消失的类型转换功能,打印输出变为 在默认 在酒吧copy_contr 在酒吧copy_contr

如此看来,编译器有一些机制可以按某种顺序搜索一些转换函数,任何人都有标准的难以说明的机制是什么?

我正在使用g ++ v4.1.2。

谢谢!

回答

2

我对第三个打印输出感到困惑:复制构造函数如何被调用,它应该是类型转换,其中存在特定的static_cast。

表达的static_cast < T>的结果(v)是转换表达式v到类型T.

的表达式e可以使用的static_cast显式转换为一个类型T的结果的形式static_cast < T>(e)如果声明T(e);对于一些发明的临时变量t来说是形式良好的。

这种显式转换的效果与执行声明和初始化相同,然后使用临时变量作为转换的结果。

由此可知,为什么在这种情况下调用转换构造函数。

我也有一个有趣的发现 - 如果我注释掉line27 - line30,基本上使消失的类型转换功能,打印输出更改为在默认情况下在酒吧copy_contr在酒吧copy_contr

你问为什么转换函数美孚::运算酒吧被选择(如果有的话)的参数转换FO从富到代替栏转换构造酒吧::栏的(常量美孚&) ....

所以看起来编译器有一些机制来按某种顺序搜索一些转换函数,任何人都有标准的难以分辨的机制是什么?

用户定义的转换只适用于他们明确的地方。但是请注意你的paticular情况如下:

  1. 富FO是非const的(即不是 “常量富FO;”)
  2. 美孚::操作栏()是非常量(即不是 “富::操作栏()const的”)
  3. 吧::酒吧(常量富&)是常量(即不 “吧::酒吧(富&)”)

疗法安伏所选择的转换是针对同样的原因美孚::运算栏()

class X 
{ 
    void f(); 
    void f() const; 
}; 

X x; 
x.f(); 

f的非const版本上面选择。 Foo fo是非const的,所以选择非const版本。

如果转换函数是const OR,则转换构造函数接受非const引用,否则会产生歧义并且不会编译。

如果转换函数是const且转换构造函数带有一个非const引用,它将选择转换构造函数而不是转换函数。

+0

谢谢。是的,如果我删除了Bar转换构造函数中的“const”,则会出现编译错误。 – 2012-03-13 01:14:07

0

您认为“铸造”和“转化”之间的区别是什么?演员要求将一个值转换为另一个值。类别类型之间的转换通过构造进行。

也许你正试图重新解释Foo对象作为酒吧?这需要不同的语法。

您在代码中使用了错误的术语。你称之为“拷贝构造函数”的两个构造函数完全不是拷贝构造函数。他们是转换构造函数。它们允许从Bar构建Foo,反之亦然。

复制构造函数允许类X的实例从类X的现有实例构造而成。

如果您将printf更改为“In ... conversion constructor”,则更有意义。

相关问题