标签: virtual-inheritance

对于从虚拟基类继承的虚函数,什么是"虚拟thunk"?

当我尝试访问从虚拟基类继承的派生类对象的内存布局时,出了点问题.
编程环境:GNU/Linux 3.19.0-32-generic,x86_64
编译器:gcc 4.8.4

//virtual base class
class Base {
public :
    virtual void f() {
        cout << "Base::f()" << endl;
    }
private:
    long x;
};

//derived class
class Derived : public virtual Base {
public:
    virtual void f() {
        cout << "Derived::f()" << endl;
    }
private:
    long y;
};

int main() {
    typedef void (*FUNC)(void);
    Derived d;

    //In my machine, sizeof(long) == sizeof(pointers). My code below is neither portable nor concise. You can just read the annotation.

    //dereference …
Run Code Online (Sandbox Code Playgroud)

c++ g++ abi virtual-inheritance vtable

7
推荐指数
1
解决办法
2609
查看次数

虚拟继承构造函数选择

为什么打印20000?代码在继承序列中一直显式调用特定的基础构造函数,但忽略指定的构造函数并使用默认构造函数.

#include <iostream>

struct Car
{
  Car() : price(20000) {}
  Car(double b) : price(b*1.1) {}
  double price;
};

struct Toyota : public virtual Car
{
  Toyota(double b) : Car(b) {}
};

struct Prius : public Toyota
{
  Prius(double b) : Toyota(b)  {}
};

int main(int argc, char** argv)
{
  Prius p(30000);

  std::cout << p.price << std::endl;

  return 0;
}
Run Code Online (Sandbox Code Playgroud)

c++ inheritance virtual-inheritance c++11

7
推荐指数
1
解决办法
169
查看次数

C++,vs 2010中的模糊继承错误

在这个例子中我对多态性的应用有些麻烦.这个问题类似于我的上一个问题

C++,虚拟继承,奇怪的抽象类+克隆问题

有3个抽象类:

class A
{
public:
    virtual A  * copy () const = 0;
    virtual ~A() = 0;
};

A::~A(){}

class B
{
public:
    virtual B  * copy () const = 0;
    virtual ~B() = 0;
};

B::~B(){}

class C: virtual public A , public B 
{
public:
    virtual C  * copy () const = 0;
    virtual ~C() = 0;
};

C::~C(){}
Run Code Online (Sandbox Code Playgroud)

和两个使用虚拟继承的继承类

class D: virtual public A
{
public:
    virtual D  * copy () const {return new D …
Run Code Online (Sandbox Code Playgroud)

c++ covariance virtual-inheritance visual-c++ visual-c++-2010

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

C++中具有虚拟继承的类大小

#include<iostream>

using namespace std;

class abc
{
    int a;
};
class xyz : public virtual abc
{
    int b;
};

int main()
{
    abc obj;
    xyz obj1;
    cout<<endl<<sizeof(obj);
    cout<<endl<<sizeof(obj1);
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

答案将取决于编译器,但当我看到这个结果时,我感到很惊讶

~/Documents/workspace/tmp ‹.rvm-›  $ ./class_sizes   

4
16
Run Code Online (Sandbox Code Playgroud)

如果我删除虚拟关键字,那么分配的大小分别为4和8,这正是我的预期.

为什么额外的空间被准确占用?我怀疑它是针对vptr表或其他类似但不确定的.

c++ virtual-inheritance

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

层次结构中的所有派生类是否都需要访问虚拟基类?

当我尝试编译以下代码时:

class A {
public:
    A(int v) : virt(v) { }
    int virt;
    int getVirt(void) const { return virt; }
};

class B : private virtual A {
protected:
    B(int v) : A(v) { }
    using A::getVirt;
};

class C : public B, private virtual A {
protected:
    C(int v) : A(v), B(v) { }
    using A::getVirt;
};

class D : public C {
public:
    D(void) : C(3) { }
    using C::getVirt;
};

#include <iostream>

int main(int argc, char *argv[]) …
Run Code Online (Sandbox Code Playgroud)

c++ constructor virtual-inheritance

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

static_cast如何与虚拟继承一起使用?

因此,使用static_cast虚拟继承进行向下转换是不可能的,但是如何进行以下向上转换:

class Base {...};
class Derived : public virtual Base {...};

...

Derived *d = new Derived();
Base *b = static_cast<Base*>(d);
Run Code Online (Sandbox Code Playgroud)

对象的内存布局:

[ derived part | base part ]
Run Code Online (Sandbox Code Playgroud)

我知道向上转换被认为是"安全的",但是当继承是虚拟的时,编译器如何知道编译时对基础子对象的偏移?是否static_cast使用vtable

当我们有这样的事情时,这尤其令人困惑(注意它不是虚拟的):

class Third : public Derived {...};

...

Derived *d = new Third();            // non-virtual upcast, no offset will be added
Base *b = static_cast<Base*>(d);
Run Code Online (Sandbox Code Playgroud)

这次我使用相同的static_cast线,但Base子对象的偏移量是不同的!

对象的内存布局:

[ derived part | third part | base part ]
Run Code Online (Sandbox Code Playgroud)

那么如何在编译时确定它是否取决于对象的实际动态类型d指向?

c++ oop virtual-inheritance static-cast

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

修复C++多重继承模糊调用

我有三个类这样的结构:

#include <iostream>
using namespace std;

class Keyword
{
    public:
        virtual float GetValue() = 0;
};

class CharacterKeyword : public Keyword
{
    public:
        virtual float GetValue(){return _value;}
    private:
        float _value;
};

class MeasurementKeyword : public Keyword
{
    public:
        virtual float GetValue(){return _value;}
    private:
        float _value;
};

class AddressType : public CharacterKeyword, public MeasurementKeyword
{

    private:
        float address;
        float addresExt;
};

int main()
{
    AddressType *a = new AddressType();
    a->GetValue();
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

我得到以下内容:

In function ‘int main()’:
error: request for …

c++ virtual-inheritance diamond-problem

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

继承构造函数和虚拟基类

我即将创建一个异常类层次结构,概念上看起来像这样:

#include <iostream>
#include <stdexcept>

class ExceptionBase : public std::runtime_error {
public: 
    ExceptionBase( const char * msg ) : std::runtime_error(msg) {}
};

class OperationFailure : virtual public ExceptionBase {
public: 
    using ExceptionBase::ExceptionBase;
};

class FileDoesNotExistError : virtual public ExceptionBase {
public: 
    using ExceptionBase::ExceptionBase;
};

class OperationFailedBecauseFileDoesNotExistError
    : public OperationFailure, FileDoesNotExistError {
public: 
    using ExceptionBase::ExceptionBase; // does not compile
};

int main() {
    OperationFailedBecauseFileDoesNotExistError e("Hello world!\n");

    std::cout << e.what();
}
Run Code Online (Sandbox Code Playgroud)

所有构造函数应该与ExceptionBase类的构造函数相同.派生的异常仅在类型上有所不同,否则没有添加的功能.上面代码中提到的最后一个异常类型也应该有这些构造函数.这是否可以使用C++ 11标准的继承构造函数功能?如果那是不可能的:还有什么选择?

(顺便说一句:在上面的代码中的类OperationFailureFileDoesNotExistError.没有用gcc 4.8编译,但铿锵3.4显然,海湾合作委员会拒绝为虚拟基础继承构造函数这将是有趣的,知道谁在这里两种编译器拒绝了类OperationFailedBecauseFileDoesNotExistError …

c++ virtual-inheritance c++11 inheriting-constructors

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

虚拟继承是否强制基类是默认可构造的?

在以下代码中,编译器请求基类X默认可构造的.但是,如果我删除虚拟从继承关键字类节点,接入到成员m_x变,当然,暧昧的,但默认构造函数类X不再需要.

这是什么原因?

#include <iostream>

struct Apply
{
    template< typename T >
    struct Node : virtual T    // this line contains the virtual inheritance
    {
        template< typename ...Args>
        Node( Args... args )
            : T( args... )
        {}
    };

    template < typename ...BaseClasses>
    struct Inheritance;

    template < typename FirstBaseClass, typename ...OtherBaseClasses>
    struct Inheritance< FirstBaseClass, OtherBaseClasses... >   : FirstBaseClass
            , Inheritance< OtherBaseClasses... >
    {
        template< typename ...Args>
        Inheritance( Args... …
Run Code Online (Sandbox Code Playgroud)

c++ virtual-inheritance default-constructor template-meta-programming variadic-templates

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

使用虚拟继承的地址未对齐

以下显然有效的代码使用UndefinedBehaviorSanitizer sanitiser产生错位的地址运行时错误.

#include <memory>
#include <functional>

struct A{
  std::function<void()> data; // seems to occur only if data is a std::function
} ;

struct B{
  char data; // occurs only if B contains a member variable
};

struct C:public virtual A,public B{

};

struct D:public virtual C{

};

void test(){
  std::make_shared<D>();
}

int main(){
  test();
  return 0;
}
Run Code Online (Sandbox Code Playgroud)

在macbook上编译和执行 clang++ -fsanitize=undefined --std=c++11 ./test.cpp && ./a.out 产生输出 runtime error: constructor call on misaligned address 0x7fe584500028 for type 'C', which requires 16 byte …

c++ memory-alignment virtual-inheritance sanitizer clang++

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