虚拟继承和构造函数传播 [英] Virtual inheritance and constructor propagation

查看:113
本文介绍了虚拟继承和构造函数传播的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

大家好,

我目前正在从事的项目使用Qt和OpenGL.确实,这与问题无关紧要.

在我的QMainWindow上,我想要一个指向小部件"的指针,该指针将用于实现我从现在开始编写的小部件中的所有常用功能.另一方面,我还需要从QGLWidget继承.这就是我写的:

Hello everyone,

The project I''m currently working on uses Qt and OpenGL. Not that it matters for the question, really.

On my QMainWindow I want a pointer to a "Widget" that I''ll use to implement all common functionalities in the widgets I write from now on. On the other hand, I''ll also need to inherit from QGLWidget. So this is what I wrote:

QWidget
Widget : public QWidget
QGLWidget : public QWidget (looked it up)
GLWidget : public QGLWidget, public Widget



这是一个即时的钻石问题.因此,我寻找解决方案,并发现了虚拟继承".如果我做对了,即使vtable变大了,使用虚拟继承也只能得到一个通用基类的实例.所以我这样写:



This is an instant diamond problem. So I looked up for solutions and found out about "virtual inheritance". If I got this right, using virtual inheritance I get only one instance of the common base class, even though the vtable gets bigger. So I wrote this:

QWidget
Widget : public virtual QWidget
QGLWidget : public QWidget
GLWidget : public virtual QGLWidget



要提问,然后:

1)这是否符合我的想法?我的意思是,如果我从Widget或GLWidget(应该再次用作基类)继承(又再次),则每个类仅获得一个实例吗?

2)构造函数传播如何?假设我正在实现QGLWidget.我该在哪里传播构造函数调用?小部件? QGLWidget?还是两者都有?

提前谢谢大家=)
问候



To questions, then:

1) Does this do what I think it does? I mean, do I get only one instance of each class if I inherit (yet again) from either Widget or GLWidget (they are supposed to be used as base classes).

2) What about constructor propagation? Say I''m implementing QGLWidget. Where do I propagate the constructor call? Widget? QGLWidget? Or both?

Thank you all in advance =)
Kind regards

推荐答案

查看 http://www.cprogramming.com/tutorial/virtual_inheritance.html [
Check out http://www.parashift.com/c++-faq-lite/multiple-inheritance.html#faq-25.9[^] or http://www.cprogramming.com/tutorial/virtual_inheritance.html[^]

Note that to solve your problem, both intermediate derived classes must inherit virtually, not just one of them.


如果您更改
If you change
class GLWidget : public QGLWidget, public Widget { }




to

class GLWidget : public virtual  QGLWidget { }


您将无法获得与第一个示例相同的结果,因为Widget公开的任何方法在GLWidget的实例上将不可用(就像在第一个示例中一样),因为您已经完全从继承树中删除了Widget.

要获取初始继承树,但每个父对象只有一个实例(virtual继承),您可以进行如下操作;


you won''t achieve the same as in the first example, because any methods exposed by Widget will not be available on an instance of GLWidget (as they would be in the first example), since you''ve completely removed Widget from the inheritance tree.

To get the initial inheritance tree, but with only one instance of each parent (virtual inheritance) you could go for something like this;

#include<iostream>

using namespace std;

class QWidget
{
public:
	int value;

	QWidget(int param)
	{
		value = param;
	}

	virtual ~QWidget()	{ }
};

class Widget : public virtual QWidget
{
public:
	Widget(int paramA, int paramB)
		: QWidget(paramA * 10)
	{
	}

	virtual ~Widget()	{ }
	virtual void Foo()	{ }
};

class QGLWidget : public virtual QWidget
{
public:
	QGLWidget(int paramA, int paramB, int paramC)
		: QWidget(paramA)
	{
	}

	virtual ~QGLWidget() { }
};

class GLWidget : public virtual QGLWidget, public virtual Widget 
{
public:
	GLWidget(int paramA, int paramB, int paramC, int paramD)
		:  QGLWidget(paramA, paramB, paramC), Widget(paramA, paramB), QWidget(45)
	{
	}

	virtual ~GLWidget()	{ }
};

int main(int argc, char* argv[])
{
	GLWidget w(1, 2, 3, 4);
	cout << w.value << endl;
	w.Foo();
	return 0;
}



请注意,尽管如此,您将必须一直指定构造函数参数,例如,此示例显示45(因为不仅从GLWidget构造函数调用QGLWidgetWidget的构造函数,而且还从QWidget构造函数调用该构造函数).

希望这会有所帮助,
弗雷德里克(Fredrik)



Notice that you will have to specify constructor arguments all the way down though, this example prints 45 for example (as the constructor of not only QGLWidget and Widget are called from the GLWidget constructor but also that of QWidget).

Hope this helps,
Fredrik


这篇关于虚拟继承和构造函数传播的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆