标签: virtual-inheritance

C++多虚拟继承与COM

网上满是"可怕的钻石问题"的解释.StackOverflow也是如此.我想我明白这一点,但我没有将这些知识转化为理解类似但不同的东西.

我的问题始于一个纯粹的C++问题,但答案很可能转移到MS-COM细节中.一般问题是:

class Base { /* pure virtual stuff */ };
class Der1 : Base /* Non-virtual! */ { /* pure virtual stuff */ };
class Der2 : Base /* Non-virtual! */ { /* pure virtual stuff */ };
class Join : virtual Der1, virtual Der2 { /* implementation stuff */ };
class Join2 : Join { /* more implementation stuff + overides */ };
Run Code Online (Sandbox Code Playgroud)

不是经典的钻石解决方案.究竟"虚拟"在这里做什么?

我真正的问题是试图理解我们朋友在CodeProject上讨论.它涉及一个自定义类,用于为Flash播放器创建透明容器.

我以为我会尝试这个地方的乐趣.事实证明,以下声明使您的应用程序崩溃,其中包含Flash播放器的第10版.

class FlashContainerWnd:   virtual public …
Run Code Online (Sandbox Code Playgroud)

c++ com multiple-inheritance virtual-inheritance

6
推荐指数
1
解决办法
2607
查看次数

gcc 4.5.1虚拟继承问题

让我们从代码片段开始:

#include <iostream>

struct God{
    God(){_test = 8;}
    virtual ~God(){}
    int _test;
};

struct Base1 : public virtual God{
    //Base1(){std::cout << "Base1::Base1" << std::endl;}  //enable this line to fix problem
    virtual ~Base1(){}
};

struct Base2 : public virtual Base1{
    virtual ~Base2(){}
};

struct A1 : public virtual Base2{
    A1(){std::cout << "A1:A1()" << std::endl;}
    virtual ~A1(){};
};

struct A2 : public virtual Base2{
    A2(){std::cout << "A2:A2()" << std::endl;}
    virtual ~A2(){};
};


struct Derived: public virtual A1, public virtual A2{
    Derived():Base1(){std::cout << …
Run Code Online (Sandbox Code Playgroud)

c++ virtual-inheritance

6
推荐指数
1
解决办法
234
查看次数

虚拟继承和接口

class IA
{
public:
    virtual void a() = 0;
};

class A: virtual public IA
{
public:
    virtual void a()
    {
    }
};

class IB: virtual public IA
{
public:
    virtual void b() = 0;
};

class B: virtual public IB, public A
{
public:
    virtual void b()
    {
    }
};
Run Code Online (Sandbox Code Playgroud)

你是否总是像我一样继承你的界面虚拟?如果没有,您将如何强制执行上述代码?

c++ virtual-inheritance

6
推荐指数
1
解决办法
1986
查看次数

C++:是一个具有虚拟基础的类但没有虚函数的多态并且具有VTable?

请考虑以下代码:

#include <iostream>
#include <typeinfo>
#include <type_traits>

using namespace std;

struct A { int data; };
struct B1 : A {};
struct B2 : virtual A {};

struct Base1 : virtual A {};
struct Base2 : virtual A {};
struct Derived : Base1, Base2 {};

int main() {
  cout << sizeof(B1) << endl;
  cout << sizeof(B2) << endl;
  cout << sizeof(Derived) << endl;

  cout << std::is_polymorphic<B1>::value << endl;
  cout << std::is_polymorphic<B2>::value << endl;
  cout << std::is_polymorphic<Derived>::value << endl;
  return 0; …
Run Code Online (Sandbox Code Playgroud)

c++ polymorphism virtual-functions rtti virtual-inheritance

6
推荐指数
1
解决办法
939
查看次数

为什么C++显式实例化的模板方法不能覆盖虚方法?

为什么以下代码中的TemplateChild不起作用?我知道虚方法不能是模板,但为什么显式实例化模板方法不能覆盖虚方法?

#include <iostream>

class VirtBase
{
public:
    VirtBase() {};
    virtual ~VirtBase() {};

    virtual void method( int input ) = 0;
    virtual void method( float input ) = 0;
};

class RegularChild : public VirtBase
{
public:
    RegularChild() {};
    ~RegularChild() {};

    void method( int input ) {
        std::cout << "R" << input << std::endl;
    }
    void method( float input ) {
        std::cout << "R" << input << std::endl;
    }
};

class TemplateBounceChild : public VirtBase
{
public:
    TemplateBounceChild() {};
    ~TemplateBounceChild() {}; …
Run Code Online (Sandbox Code Playgroud)

c++ templates virtual-inheritance

6
推荐指数
2
解决办法
1117
查看次数

这种使用"方法注入"的虚拟继承模式是一种已知的范例吗?

昨天,我遇到了这个问题:迫使不合格的名称成为依赖值最初,它似乎是一个与破坏的VC++行为有关的非常具体的问题,但在尝试解决它时,我偶然发现了虚拟继承的使用模式我没有之前遇到过(在我告诉你问题之后,我会在一秒钟内解释).我发现它很有趣,所以我在SO和google上寻找它,但我找不到任何东西.也许,我只是不知道它的正确名称("方法注入"是我的猜测之一),它实际上是众所周知的.这也是我对社区提问的一部分:这是一种常见的使用模式还是另一种已知范式的特例?您是否看到任何可以通过其他解决方案避免的问题/陷阱?

此模式可以解决的问题如下:假设您有一个Morph带有方法的类doWork().在其中doWork(),调用了几个函数,其实现应该由用户选择(这就是调用类的原因Morph).让我们称之为函数变色龙(因为Morph类最终不知道它们将是什么).实现这一目标的一种方法当然是使变色龙成为Morph类的虚方法,这样用户就可以派生出来Morph并覆盖所选择的方法.但是,如果期望用户使用不同的组合来选择不同变色龙的实现,该怎么办呢?然后,对于每个组合,必须定义新类.另外,如果有多个Morph类相同的函数应该是变色龙呢?用户如何重用已经实现的替换?

至于"必须定义多个类"的问题,立即模板跳进了一个人的脑海.用户不能通过将类作为定义所需实现的模板参数来选择他想要的变色龙实现吗?即类似的东西Morph<ReplaceAB>应该有效地取代变色龙,A()并且B()doWork()某些实施中,留下可能的其他变色龙,例如C(),未触动过.使用C++ 11和可变参数模板,即使组合也不会成为问题:Morph<ReplaceAB, ReplaceC, WhateverMore...>嗯,确实,这种模式可以做什么(参见下面的解释):

#include <iostream>

using namespace std;

// list all chameleons, could also be make some of them
// pure virtual, so a custom implementation is *required*.
struct Chameleons
{
  virtual void A() { cout << "Default A" << endl; }
  virtual void B() { cout << "Default B" …
Run Code Online (Sandbox Code Playgroud)

c++ inheritance virtual-inheritance

6
推荐指数
1
解决办法
233
查看次数

阻止虚拟继承

在现代C++中是否有一种方法可以防止类被虚拟继承,同时允许定期继承?现在对我来说似乎不可能,但这种语言中有太多东西似乎是不可能的.

c++ virtual inheritance virtual-inheritance

6
推荐指数
1
解决办法
150
查看次数

C++虚拟内存布局

了解虚拟继承内存布局

我正在努力更好地理解vTables和vPointers为我们提供的解析内存布局.我完全理解多态性及其工作原理,并且确实没有问题,但是有一些小事情我似乎在关于内存布局和理解虚拟基本偏移方面绊倒.我知道这些东西在每天的C++代码中都不是完全必要的,但是我的兴趣是获取正在发生的事情.

我一直在指这个站点,以帮助理解由于使用虚拟继承而发生的内存布局.

在页面的虚拟继承部分大约有一半的时间内,它为生成的vTable提供了视觉效果,但是我想澄清一下我认为发生了几个事件的顺序:

http://www.phpcompiler.org/articles/virtualinheritance/vtable2.png

在上图中,在我看来:

  • 我们首先包含指向LeftvTable的vPtr
  • 接下来包括Left类的唯一值(Left::b)
  • 接下来,计算偏移量,以便我们可以在刚刚包含的数据之后直接放置任何虚拟继承的数据.vPtr的大小+ int Left::b= 8,因此我们偏移Top::a8,并将其添加到布局的底部.
  • 冲洗并重复正确的课程

http://www.phpcompiler.org/articles/virtualinheritance/vtable3.png

上面的图片,在我看来是:

  • 我们首先包括我们继承的第一类vPtr
  • 由于我们实际上并没有从该直接基类继承,我们可以直接继承特定于该类的任何非虚拟数据成员,而无需偏移即(Left::b)
  • 我们包括继承的第二类vPtr
  • 由于我们实际上并没有从该直接基类继承,我们可以直接继承特定于该类的任何非虚拟数据成员,而无需偏移即(Right::c)
  • 接下来包括Bottom该类的任何唯一数据,Bottom::d
  • 接下来,我们计算超类中虚拟数据的偏移量,并将其包含在内存布局的底部.
  • 最后,我们完成了Bottom类的内存布局

对我来说,我认为上述过程在很多情况下确定内存布局是有意义的,但是我想知道如果我改变一些事情会发生什么.

  1. 如果Bottom虚拟地继承了两者Left和内存,内存布局将如何变化Right
  2. 底部继承LeftRight定期,但是说Right定义它自己int a,显然这会使它bottom.a等于bottom.Right::a最近覆盖的任何东西,但是这将被放置在内存布局中?

我的每个问题都有一个提案布局(2),并想知道我背后的想法是否正确,如果没有,为什么......谢谢!

1.)

+--Bottom---+ …
Run Code Online (Sandbox Code Playgroud)

c++ inheritance memory-management virtual-inheritance

6
推荐指数
0
解决办法
113
查看次数

当我从虚拟基础派生D时,为什么在VS2015中sizeof(D)增加了8个字节?

我正在使用C++14§3.11/ 2中的示例:

struct B { long double d; };
struct D : virtual B { char c; }
Run Code Online (Sandbox Code Playgroud)

在clang,g ++和VS2015中运行下面的代码片段之后

#include <iostream>
struct B { long double d; };
struct D : /*virtual*/ B { char c; };

int main()
{
    std::cout << "sizeof(long double) = " << sizeof(long double) << '\n';
    std::cout << "alignof(long double) = " << alignof(long double) << '\n';

    std::cout << "sizeof(B) = " << sizeof(B) << '\n';
    std::cout << "alignof(B) = " << alignof(B) << …
Run Code Online (Sandbox Code Playgroud)

c++ alignment virtual-inheritance c++14

6
推荐指数
1
解决办法
274
查看次数

虚拟继承中的虚拟基本偏移量

代码如下(使用G ++编译的C++ 11代码 - 在Ubuntu 16.04上为5.4):

#include <iostream>

using namespace std;



class Base
{
    public:
        virtual void show()
        {
            cout << "Base" << endl;
        }

        virtual void func()
        {
            cout << "func in Base" << endl;
        }

    protected:
        int base = 15;
};

class A: public virtual Base
{
    public:
        void show() override
        {
            cout << this << endl;
            cout << 'A' << endl;
        }

        void func() override
        {
            cout << this << endl;
            cout << "func in A" << …
Run Code Online (Sandbox Code Playgroud)

c++ virtual-inheritance c++11

6
推荐指数
1
解决办法
522
查看次数