原帖地址http://bbs.csdn.net/topics/390793860,为了方便还是把示例代码贴下吧 class FBase { public: virtual void Set() { info = _T("FBase"); } void PrintInfo() { _tprintf(_T("%s\n"), info); } protected: TCHAR *info; }; class FChild : public FBase { public: void Set() { info = _T("FChild"); } }; FChild child; child.Set(); child.PrintInfo(); ((FBase)child).Set(); child.PrintInfo(); 结果是打印2次“FChild”。(FBase)child这句貌似有临时对象产生,但如果有的话却并没有调用到构造函数,如果没有的话下面这几个值都不相同,指针之间的转换还能看懂,对象间的强制转换有点不太明白这个转换过程发生了些什么,求指点。 FBase* pBase = (FBase*)&child; FBase* pBase2 = &(FBase)child; FBase* pBase3 = &(FBase)child; |
|
同不懂,求教
|
|
40分 |
直接使用 (FBase)child 这种对象的转换是有临时对象产生的,调用的不是构造函数,而是拷贝构造函数
FBase(const FBase& b) { //Copy Constructor code... } 在使用多态的时候不能使用这种对象的强制转换,而应该使用指针或者引用(楼主肯定知道^^)。如果非要深究,应该是这么回事: FChild child; child.Set(); child.PrintInfo(); //print: FChild //对对象进行类型转换,调用默认的拷贝构造函数进行浅拷贝 //此时b.info 指向 child.info 内存地址 // b.vtable 指向 FBase::vtable FBase b = (FBase)child; b.PrintInfo(); //print: FChild //给b.info 重新赋值,调用 FBase::Set() b.Set(); b.PrintInfo(); //print: FBase child.PrintInfo(); //print: FChild |
感谢,(FBase)child 按照你说的应该是用child的基类部分拷贝构造一个匿名的FBase对象,可是还是不太明白这种转换为什么会有拷贝构造的调用,是标准有规定吗 |
|
根据不同的场景调用不同的构造函数: using namespace std; class TestClass { public: TestClass(){ cout << "constructor..." << endl; } TestClass(TestClass& b) { cout << "copy constructor..." << endl;} TestClass& operator = (const TestClass& b) { cout << "assignment constructor..." << endl; return *this;} }; void TestFunc(TestClass c){} int _tmain(int argc, _TCHAR* argv[]) { //调用一般的构造函数 TestClass obj1; //constructor //创建对象并初始化,调用拷贝构造函数 TestClass Obj2(obj1); //copy constructor TestClass Obj3 = obj1; //copy constructor //传递参数,产生临时变量,调用拷贝构造函数 TestFunc(obj1); //copy constructor //赋值操作,调用赋值构造函数 Obj3 = Obj2; //assignment constructor return 0; } |
|
1 (FBase)child 肯定产生了临时对象,通过拷贝构造
2 ((FBase)child).Set();这句没有意义,因为这是对临时对象的操作,不会影响child 3 FBase* pBase = (FBase*)&child;是多态 4 FBase* pBase2 = &(FBase)child;是把一个临时FBase对象的指针赋值给pBase2 |
|
多谢,额,我的意思并不是说为什么调用的是拷贝构造而不是构造,我想问的是为什么这种转换会有对象的生成。
|
|
肯定产生了临时对象 |
|
因为这属于强制类型转换,而不是多太用到的引用或指针的转换。 |
|
10分 |
既然有类型转换,当然会产生一个对应转换后型的对象,以供拷贝或其他操作。 |
你的意思是说,这种强制转换不管是内置类型还是class类型,都会伴随着临时对象的生成? |
|
对 |
|
你指的内置类型
不是。 |
|
感谢2位的回答,过几天再结,看还有没有不同的意见的。
|
|
可是这里的强制转换不属于这3种条件的任何一种。 |
|
50分 |
这句 (FBase)child 叫 explicit type conversion (cast notation)。
标准 5.4 定义了其行为,对主楼的用例,该语句等同与 static_cast<FBase>(child),后者的行为在 5.2.9/4 定义: Otherwise, an expression e can be explicitly converted to a type T using a static_cast of the form static_cast<T>(e) if the declaration T t(e); is well-formed, for some invented temporary variable t (8.5). The effect of such an explicit conversion is the same as performing the declaration and initialization and then using the temporary variable as the result of the conversion. The expression e is used as a glvalue if and only if the initialization uses it as a glvalue. 所以 ((FBase)child).Set(); 就是 FBase e(child); // copy construction e.Set(); 第一句就是复制构造发生的点。 |
多谢指点。。 |
|
对于C风格的强制转换,以下两种方式的效果是一样的。
(T)expression //将expression转型为T类型 T(expression) //将expression转型为T类型 对于楼主的(FBase)child这样的强制转换,可以完全等同于 |