C++的子类与父类强制转换产生的问题

近日,在项目的一个类中如果碰上想要将子类强制转换成父类,然后再调用其父类版本的virtual虚函数。

就会出现gcc编译错误提示:error: ld returned 1 exit status

gcc提示原因:在link过程中,发现了无法找到的reference symbol, 该reference symbol是此父类的拷贝构造函数。

由此,我推断问题的原因是:在子类转换成父类的过程中,默认地调用了父类的拷贝构造函数。而由于项目中针对大部分类都使用了DISALLOW_COPY_AND_ASSIGN(XXX); 这个宏声明却没实现,相当于禁止了拷贝构造函数。该宏的定义如下:

#define DISALLOW_COPY_AND_ASSIGN(ClassName)
ClassName(const ClassName&); void operator=(const ClassName&)

解决方法是: 转换其类型,但是不让其使用拷贝构造函数(copy constructor),代码如下:

static_cast<Parrent&>(*this);

此处使用了Parrent& 而不是 static_cast<Parrent>(*this) , 使用引用而不是类,可以避免copy新的对象, 自然就避免了调用其拷贝构造函数。

参考:

1. http://stackoverflow.com/questions/9084835/why-does-static-castthis-to-a-base-class-create-a-temporary-copy

时间: 2024-11-12 17:03:41

C++的子类与父类强制转换产生的问题的相关文章

在Java当中父类和子类之间的强制转换

接下来的三点是我从百度知道上引用来的.嘻嘻~,感觉不错. 1.从对象的内存角度来理解.假设现在有一个父类Father,它里面的变量需要占用1M内存.有一个它的子类Son,里面的变量需要占用0.5M内存.现在通过代码来看看内存的分配情况:2.f = new Father();//系统将分配1M内存.Son s = new Son();//系统将分配1.5M内存!因为子类中有一个隐藏的引用super会指向父类实例,所以在实例化子类之前会先实例化一个父类,也就是说会先执行父类的构造函数.由于s中包含了

C++多重继承下一个子类和父类指针转换的bug

这两天有个C++新手问了我一个问题,他的工程当中有一段代码执行不正确,不知道是什么原因.我调了一下,代码如果精简下来,大概是下面这个样子: class IBaseA { public: virtual void fnA() = 0; int m_nTestA; }; class IBaseB { public: virtual void fnB() = 0; int m_nTestB; }; class CTest : public IBaseA,public IBaseB { public:

面向对象的过程、继承、封装、多态;抽象类、访问修饰符的使用、引用类型强制转换、方法重写@override与重载、空指针异常、super关键字

面向对象设计的过程:     发现类-发现类的属性-发现类的方法-优化设计: 封装: private类型的,只可以在本类中使用,当其他类调用此类时,不可使用,因此可以设置setget方法,如下所示: 构造------------------------ 默认有无参构造,若设置了有参构造,则就没有默认的无参构造了,需要自己再添加一个 方法重载------------------- 方法名相同,参数列表不同(类型,数量,顺序不同,与参数名无关): 与返回值,访问修饰符无关 面向对象(OO)的优点--

java 强制转换

在java中强制类型转换分为基本数据类型和引用数据类型两种,这里我们讨论的后者,也就是引用数据类型的强制类型转换. 在Java中由于继承和向上转型,子类可以非常自然地转换成父类,但是父类转换成子类则需要强制转换.因为子类拥有比父类更多的属性.更强的功能,所以父类转换为子类需要强制.那么,是不是只要是父类转换为子类就会成功呢?其实不然,他们之间的强制类型转换是有条件的. 当我们用一个类型的构造器构造出一个对象时,这个对象的类型就已经确定的,也就说它的本质是不会再发生变化了.在Java中我们可以通过

c++ 继承类强制转换时的虚函数表工作原理

本文通过简单例子说明子类之间发生强制转换时虚函数如何调用,旨在对c++继承中的虚函数表的作用机制有更深入的理解. #include<iostream> using namespace std; class Base { public: virtual void f() { cout<<"Base::f()"<<endl; } }; class child1:public Base { public: virtual void f() { cout&l

基类与子类之间的引用转换

(一) 从该源代码中可看出,子类可直接赋给基类(“基类变量=子类对象”):基类的引用类型要传递给子类必须通过强制转换(“子类变量=(子类名)基类对象”): 子类之间不可以进行转换. (二) 该源代码可总结出: 当基类与子类有同名的变量时,以引用变量为准,引用变量是谁,就调用哪个类的变量:当基类与子类有同名的方法时,以具体对象类型为准,对象是什么类型,就调用哪个类的方法:基类与子类之间的转换:基类变量可以直接引用子类对象,或者直接将子类对象赋给基类变量:但是基类对象要转换为子类变量时,就必须进行强

求解:为什么父类没有的属性,在强制转换成子类后却有值了

foreach (M912 m912 in m912List) { var m934 = (M934)m912; //强制转换后,父类M912 中没有的属性m918List在转换后的子类m934中能访问且有值 } 说明:其中M912 是父类M934 是子类 m918List是子类M934的一个属性 疑问,为什么父类没有的属性,在强制转换成子类后却有值了,这种情况是如何实现的? ************************************ 问题:将子类实例赋值给父类的实例后,子类对象所

final,static静态和非静态,初始化和代码块的区别、父类和子类中都有static变量时的初始化顺序、重写equals()、 instanceof强制转换

final:类不能被继承,方法不能被重写,属性值不能被修改(常量): 可以调用: static静态常量----- 不需要创建对象,可以直接调用类里面的属性,方法: 示例如下: 加了static说明它是属于整个类的,每个对象值都一样,如下图所示:size是静态的,所以当在下面t1对象中改变size的值时,整个类中的size值都变了:然后作为普通属性的length,当在t1对象中改变其值,并不会改变原始值: 静态方法不能调用非静态的方法和非静态的属性,也不能打印非静态的方法和非静态的属性:可以在静态

Java中父类强制转换为子类的可能

之前徒弟问了一个问题, 在Java中, 父类对象到底能不能转换成对应的子类对象? 到底能不能, 今天就来说说这个问题, 先看下面一段代码: package cn.com.hanbinit.test; /** * 检验父类是否可以强转为子类 * @author icer * */ public class ConvertPro extends Father { public static void main(String[] args) { Father father = new Father()