关于函数参数类型隐式转换与子类类型有关问题,小弟我与vs2003编译器的理解不同

关于函数参数类型隐式转换与子类类型问题,我与vs2003编译器的理解不同
先看下源代码,函数内容不用管,骗编译器的,只看接口。

编译环境:VS2003   7.1.3088

class   A
{
};

class   B
{
public:
operator   A*()   {   return   NULL;   };
};

class   C
{
public:
operator   B()   {   B   b;   return   b;   };
};

class   D   :   public   A
{
};

class   E
{
public:
operator   D*()   {   return   NULL;   };
};

class   F
{
public:
operator   D()   {   D   d;   return   d;   };
};

void   foo1(A*   a)   {};

void   foo3(A   a)   {};

int   main()
{
B   b;
C   c;
E   e;
F   f;

foo1(b);   //   1
foo1(c);   //   2

foo1(e);   //   3
foo3(f);   //   4

return   0;
}

首先,我知道的原则,编译器在匹配函数参数时,不会为你做2次隐式转换(记不清确切术语了,请原谅),因此,上面注释1的地方可以成功,注释2的地方会编译失败。这个没问题。

但是对于3和4,我就比较惊讶,特别是4。

对于3来说,存在隐式转换将e变成D*类型,但是foo1要求的是A*。   这个能编译通过,我姑且算作子类指针永远可以看成父类指针,因此不需要转换。

但是对于4来说,将f转换成D类型,居然就可以直接匹配A类型?

也许我对继承的理解有误?继承下来的子类,不必作任何转换就可以看作父类类型?这么说倒是也很合逻辑。。。

企盼达人解惑。

------解决方案--------------------
class A
{
public:
virtual void print() { cout < < "A::print() " < < endl; }
};

class B: public A
{
public:
virtual void print() { cout < < "B::print() " < < endl; }
};

void f(A a)
{
a.print(); // 调用 A::print()
}

int main()
{
B b;
f(b); // 这里传参时调用了(编译器提供的)拷贝构造函数
return 0;
}

如果要定义拷贝构造函数,比如上面类A
A::A(const A& a)
{
// 这里的a时一个指向基类的引用,当然a也可以指向子类(和指针一样),所以子类是可以直接用来构造基类的
// ...
}

------解决方案--------------------
去看《C++ Primer》3e P649
章节:对用户定义的转换序列划分等级
------解决方案--------------------
也许我对继承的理解有误?继承下来的子类,不必作任何转换就可以看作父类类型?
===========
可以这么认为,
这个转换其实是一个 对象截取,
总是可以从一个 子类对象中 截取出父类子对象的。
------解决方案--------------------
对于3来说,存在隐式转换将e变成D*类型,但是foo1要求的是A*。 这个能编译通过,我姑且算作子类指针永远可以看成父类指针,因此不需要转换。

---------

这个本来派生,多态就是这样,派生类指针永远是基类指针


struct base
{
int n1;
int n2;
int n3;
int n4;
};

struct derive : public base
{

};

void fun(base s)
{

}

int main(void)
{
derive d;
fun(d);

}

这个是能编过运行,所以你的 4 也就没问题


这并没有2次转换,而是直接把派生类截取到基类

看看asm就知道了



------解决方案--------------------
ISO C++ Standard (ISO14882) 2003.pdf里找的。

12.3 P192

At most one user-defined conversion (constructor or conversion function) is implicitly applied to a single
value.

下面包含User-defined conversion的定义:

Type conversions of class objects can be specified by constructors and by conversion functions. These conversions
are called user-defined conversions and are used for implicit type conversions (clause 4), for
initialization (8.5), and for explicit type conversions (5.4, 5.2.9).