我对vptr和内存中对象的表示感到困惑,希望你能帮助我更好地理解这个问题.
考虑B从中继承A并定义虚函数f().从我了解到的记忆B类对象的表示是这样的:[ vptr | A | B ]
与vtbl该vptr指向包含B::f().我也明白,从铸造对象B来A什么都不做,除了忽略B在对象的端部.这是真的吗?这种行为不对吗?我们希望类型的对象A执行A::f()方法而不是B::f().
是否有一些vtables在系统中的类的数量?
一个将如何vtable类,由两个或多个类继承的是什么样子?如何将C的对象表示在内存中?
与问题3相同,但具有虚拟继承.
我有一个实现引用计数的C++类,我希望这个类的所有用户只能虚拟地继承这个类,这样任何对象都不会有多个引用计数器.
我想在编译时或至少在运行时期间以某种方式断言这个要求.
有没有办法实现这一目标?
我们都知道,在使用简单单继承时,派生类的地址与基类的地址相同。多重继承使这一点变得不真实。
虚拟继承是否也使这不真实?换句话说,以下代码是否正确:
struct A {};
struct B : virtual A
{
int i;
};
int main()
{
A* a = new B; // implicit upcast
B* b = reinterpret_cast<B*>(a); // fishy?
b->i = 0;
return 0;
}
Run Code Online (Sandbox Code Playgroud) 基于http://en.wikipedia.org/wiki/Virtual_inheritance
class Animal
{
...
};
// Two classes virtually inheriting Animal:
class Mammal : public virtual Animal
{
...
};
Run Code Online (Sandbox Code Playgroud)
我还看到书籍使用以下语法,
class Mammal : virtual public Animal
{
...
};
Run Code Online (Sandbox Code Playgroud)
问题>哪个是C++标准?
谢谢
此代码被(至少)MSVC,ICC和GCC拒绝:
class A {
public:
A( int ) { }
};
class B: virtual public A {
public:
//B(): A( -1 ) { } // uncomment to make it compilable
virtual void do_something() = 0;
};
class C: public B {
public:
C(): A( 1 ) { }
virtual void do_something() { }
};
int main() {
C c;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
在...的基础上
error : no default constructor exists for class "A"
class B: virtual public A {
^
detected …Run Code Online (Sandbox Code Playgroud) 我们在项目中有一个特殊的接口框架,部分要求是代表接口的类只能用作虚拟基类,而不能用作非虚拟基类.有没有办法在代码中强制执行此操作?也就是说,如果类是从非虚拟派生的,则产生编译错误.
我可以访问由VS 2010实现的C++ 11:这意味着static_assert,enable_if并且<type_traits>可用.
在以下代码中:
class A
{
public:
int x;
A(int x):x(x){}
};
class B: public virtual A
{
public:
B(int x):A(x){}
};
class C: public virtual A
{
public:
C(int x):A(x){}
};
class D: public B, public C
{
public:
D(int x):B(x++), C(x++), A(x++){}
};
Run Code Online (Sandbox Code Playgroud)
两个问题:
A(...)D的初始化列表?D(int x):B(x++), C(x++), A(x++){}并且D(int x):A(x++), B(x++), C(x++){}均可以得到同样的结果cout<<D(10).x,为什么呢?c++ inheritance constructor multiple-inheritance virtual-inheritance
#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):A(obj){cout<<"4";}
};
class C: virtual A
{
public:
C(){cout<<"5";}
C(const C & obj):A(obj){cout <<"6";}
};
class D:B,C
{
public:
D(){cout<<"7";}
D(const D & obj):C(obj),B(obj){cout <<"8";}
};
int main()
{
D d1;
D d(d1);
}
Run Code Online (Sandbox Code Playgroud)
我得到 13571468 作为输出。但我认为输出应该是 13572468。为什么运行普通构造函数而不是类 A 的复制构造函数?
c++ inheritance constructor copy-constructor virtual-inheritance
我读了一个问题:C ++虚拟类继承对象大小问题,并且想知道为什么虚拟继承会在类中导致附加的vtable指针。
我在这里找到了一篇文章:https : //en.wikipedia.org/wiki/Virtual_inheritance
告诉我们:
但是,通常只能在运行时知道此偏移量,...
我在这里不了解与运行时相关的内容。完整的类继承层次结构在编译时就已经知道。我了解虚函数和基指针的用法,但是虚继承没有这种东西。
有人可以解释为什么某些编译器(Clang / GCC)使用vtable实现虚拟继承以及在运行时如何使用它吗?
顺便说一句,我也看到了这个问题:在虚拟继承的情况下使用vtable,但是它仅指向与虚拟函数相关的答案,这不是我的问题。
我的理解,例如阅读本文,是派生类的构造函数不会调用其虚拟基类的构造函数。
这是我制作的一个简单示例:
class A {
protected:
A(int foo) {}
};
class B: public virtual A {
protected:
B() {}
};
class C: public virtual A {
protected:
C() {}
};
class D: public B, public C {
public:
D(int foo, int bar) :A(foo) {}
};
int main()
{
return 0;
}
Run Code Online (Sandbox Code Playgroud)
出于某种原因,构造函数B::B()和C::C()正在尝试初始化A(在我的理解中,此时应该已经初始化了D):
$ g++ --version
g++ (GCC) 10.2.0
Copyright (C) 2020 Free Software Foundation, Inc.
This is free software; see …Run Code Online (Sandbox Code Playgroud)