标签: virtual-inheritance

虚拟功能背景下的主导地位是什么?

代码示例:

考虑以下菱形层次结构:

struct A
{
    virtual void f(){}
    void g(){}
};    
struct B : virtual A
{
    virtual void f() override{}
    void g(){}
};     
struct C : virtual A
{   
};    
struct D: B, C
{    
};

int main()
{
    D d;
    d.f(); //B::f is called
    d.g(); //B::g is called
}
Run Code Online (Sandbox Code Playgroud)

我的理解:

就非虚拟功能g而言,一切都很清楚:名称B::g隐藏A::g,即使名称A::g可以在不被隐藏的情况下到达C.没有含糊之处.B::g叫做.该标准在10.2 p.10中明确证实了这一点:

[注意:当使用虚拟基类时,可以沿着不通过隐藏声明的子对象点阵的路径到达隐藏声明.这不是含糊不清的.与非虚拟基类相同的用法是模棱两可的; 在这种情况下,没有唯一的名称实例隐藏所有其他名称. - 尾注] [示例:

此外,对相关问题的这个答案提供了对该问题的详尽解释.

问题:

我不明白的是上面提到的引用如何与虚函数有关f.没有名字隐藏 …

c++ virtual-functions virtual-inheritance language-lawyer c++11

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

如何调用所有基类的复制构造函数来复制C++中钻石继承中的大多数派生类对象?

考虑以下代码:

#include<iostream>
using namespace std;
class A
{
public:
     A() {cout << "1";}
     A(const A &obj) {cout << "2";}
};

class B: virtual A
{
public:
    B() {cout << "3";}
    B(const B & obj) {cout<< "4";}
};

class C: virtual A
{
public:
   C() {cout << "5";}
   C(const C & obj) {cout << "6";}
};

class D:B,C
{
public:
    D()  {cout << "7";}
    D(const D & obj) {cout << "8";}
};

int main()
{
   D d1;
   cout << "\n";
   D …
Run Code Online (Sandbox Code Playgroud)

c++ copy-constructor virtual-inheritance private-inheritance ctor-initializer

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

MSVC:协变返回类型和虚拟继承

我不确定这是否是 Visual-C++ 编译器中的错误或未定义的行为。

设置

struct DummyBase { virtual ~DummyBase() = default; };
struct DummyDerived : virtual public DummyBase {};
Run Code Online (Sandbox Code Playgroud)

只是一个类和一个使用虚拟继承的派生类

DummyDerived derived;
DummyBase* base = &derived;

std::cout << "Derived : " << &derived << std::endl;
std::cout << "Base    : " << base << std::endl;
Run Code Online (Sandbox Code Playgroud)

当投射DummyDerived*DummyBase*指针时发生偏移。这似乎是由虚拟继承引起的:

Derived : 00000000002CF838
Base    : 00000000002CF840
Run Code Online (Sandbox Code Playgroud)

即使指针值不同,比较也会返回 true:

std::cout << "IsSame  : " << (base == &derived) << std::endl << std::endl;
Run Code Online (Sandbox Code Playgroud)

输出:

IsSame  : 1
Run Code Online (Sandbox Code Playgroud)

到目前为止,一切都很好。

问题

问题出现在以下设置中:

 struct IBaseReturner
 { …
Run Code Online (Sandbox Code Playgroud)

c++ virtual-inheritance visual-c++ visual-studio-2013 covariant-return-types

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

GCC 上虚拟继承行为的奇怪默认空构造函数

我的代码中有以下情况,即派生类具有对基类的虚拟继承:

class Base {
    int x;
public:
    Base(int x): x{x} {}
    virtual void f() = 0;
};

class Derived : public virtual Base  {
  public:
    Derived() = default;
};

class Concrete: public Derived {
public:
    Concrete(): Base{42} {}
    void f() override {}
};
Run Code Online (Sandbox Code Playgroud)

链接:https : //godbolt.org/z/bn1EY6

GCC (trunk) 给出以下错误:error: use of deleted function 'Derived::Derived()'while Clang (trunk) 编译它没有问题。

如果我将构造函数更改为Derived() {}而不是Derived() = default在基类上定义一个空的构造函数,则GCC 可以工作。

为什么= default在这种情况下删除 GCC 中的功能?

c++ gcc clang virtual-inheritance

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

无法强制转换具有多重继承的类

我试图重构一些代码,同时保留现有的功能.我无法将指向对象的指针转换为基接口,然后在以后获取派生类.在某些情况下,程序使用工厂对象来创建这些对象的实例.

以下是我正在使用的类的一些示例.

// This is the one I'm working with now that is causing all the trouble.
// Some, but not all methods in NewAbstract and OldAbstract overlap, so I
// used virtual inheritance.
class MyObject : virtual public NewAbstract, virtual public OldAbstract { ... }

// This is what it looked like before
class MyObject : public OldAbstract { ... }

// This is an example of most other classes that use the base interface
class NormalObject : public …
Run Code Online (Sandbox Code Playgroud)

c++ casting multiple-inheritance virtual-inheritance

5
推荐指数
1
解决办法
3105
查看次数

虚拟继承不破坏静态组合?

我在过去5年的工作中假设虚拟继承打破了静态组合.

但是现在我发现,静态组合仍然保持不变,只有关于正确实例位置的附加信息.这是正确的吗?

c++ virtual-inheritance

5
推荐指数
1
解决办法
897
查看次数

复杂的钻石问题:C++虚拟继承

我有一个钻石问题,看起来像这样:

    __ A
  /    |\
 |  B  |  \
v|/v v\|v  \v
 B2   B3    C
  \v  /v   /
    B4    /
     \   /
       D
Run Code Online (Sandbox Code Playgroud)

我尝试了很多方法来制作最好的虚拟继承,以获得没有重复,但我找不到解决方案.A类包含一个位置.这是一个示例输出:

Call: A() position pointer is: 0x2203be8
Call: B()
Call: B2() position pointer is: 0x2203be8
Call: B3() position pointer is: 0x2203be8
Call: C() position pointer is: 0x2203a28
Call: B4() position pointer is: 0x2203be8
Call: D() position pointer is: 0x2203a28
Run Code Online (Sandbox Code Playgroud)

为什么D和C没有相同的位置指针?为什么这个A ::位置没有构造函数?我应该用什么虚拟继承来解决这个问题?谢谢.

编辑:

这是一个代码示例:

class A;
class B;
class B2 : public virtual B, public virtual A;
class …
Run Code Online (Sandbox Code Playgroud)

c++ multiple-inheritance virtual-inheritance

5
推荐指数
1
解决办法
419
查看次数

如何从非多态虚拟基类转发?

当没有涉及虚函数时,有没有办法从虚拟基类转发到派生类?这里有一些代码来演示我在说什么:

struct Base1
{
  int data;
};

struct Base2
{
  char odd_size[9];
};

struct ViBase
{
  double value;
};


struct MostDerived : Base1, Base2, virtual ViBase
{
  bool ok;
};


void foo(ViBase &v)
{
  MostDerived &md = somehow_cast<MostDerived&>(v);  //but HOW?
  md.ok = true;
}


int main()
{
  MostDerived md;
  foo(md);
}
Run Code Online (Sandbox Code Playgroud)

请注意,该代码仅用于演示.我的真实场景相当复杂,涉及模板参数和从一个到另一个的转换,只知道第一个是第二个的基础; 它可以是普通或虚拟的基础,它可能有也可能没有虚函数.(参见底部的简化示例).我可以使用类型特征检测多态情况和虚拟/非虚拟基本情况,并解决除非多态虚拟基础之外的所有情况.这就是我要问的问题.

我真的想不出一种做演员的方法:

  • 隐含的转换是正确的; 这些只做了预告.

  • static_cast 明确禁止从虚拟基类进行转换:

    5.2.9/2 ...并且B既不是虚拟基类,D也不是虚基类的基类D....

  • dynamic_cast 也不能这样做,因为downcast需要一个多态类

    5.2.7/6否则,v应该是指向多态类型的指针或glvalue(10.3).

    10.3/1 ...声明或继承虚函数的称为多态类.

  • reinterpret_cast 在这里根本不适用.

如果 …

c++ virtual-inheritance downcast

5
推荐指数
1
解决办法
788
查看次数

继承虚拟基类的构造函数

虚拟基类在最派生的类中初始化,所以我的猜测是继承基类的构造函数也应该工作:

struct base {
    base(int) {}
};

struct derived: virtual base {
    using base::base;
};

derived d(0);
Run Code Online (Sandbox Code Playgroud)

但是,这无法使用GCC 5.2.0进行编译,GCC 5.2.0尝试查找base::base(),但与Clang 3.6.2一起正常工作.这是GCC中的错误吗?

c++ gcc g++ virtual-inheritance c++11

5
推荐指数
1
解决办法
283
查看次数

如何在虚拟继承中构造直接基础?

在下面的代码中,我试图创建一个Leaf对象obj来查看多层继承中的构造函数顺序,但我发现obj在这种情况下构造函数调用的结构有点奇怪.

#include<iostream>
using namespace std;
class Base1 { 
public:
    Base1(void) { 
        cout << "class Base1" << endl; 
    } 
}; 
class Base2 {
public: 
    Base2(void) { 
        cout << "class Base2" << endl; }
};
class Level1 : public Base2, virtual public Base1
{
public:
    Level1(void)
    {
        cout << "class Level1" << endl;
    }
};

class Level2 : public Base2, virtual public Base1
{
public:
    Level2(void)
    {
        cout << "class Level2" << endl;
    }
};

class …
Run Code Online (Sandbox Code Playgroud)

c++ inheritance multiple-inheritance virtual-inheritance

5
推荐指数
1
解决办法
117
查看次数