C++中虚继承的一个有关问题,真心不懂啊希望大侠们帮忙解答一上
C++中虚继承的一个问题,真心不懂啊,希望大侠们帮忙解答一下啊
#include <iostream>
using namespace std;
class a
{
public:
a() {}
//~a(){}
int my;
virtual void draw()
{
cout<<"a draw"<<endl;
}
};
class test_b :public virtual a
{
public:
//test_b(){}
//~test_b(){}
public:
virtual void draw2()
{
cout<<"b draw"<<endl;
//return 0;
}
};
class test_b_: public virtual a
{
public:
test_b_(){};
//~test_b_(){};
virtual void draw()
{
cout<<" draw"<<endl;
//return 0;
}
};
class c:public test_b,public test_b_
{
public:
c(){}
~c(){}
virtual void draw()
{
cout<<"draw"<<endl;
//return 0;
}
};
int main()
{
cout<<sizeof(a)<<endl;
cout<<sizeof(test_b)<<endl;
cout<<sizeof(test_b_)<<endl;
cout<<sizeof(c)<<endl;
system("pause");
return 0;
}
在这里如果我在test_b里面加构造和析构函数的话sizeof得到的值就是16如果不加就是12,test_b_和c这两个类也是,只要加构造和析构就比不加多四个字节,为什么?虚继承到底都改变了些什么啊?
------解决方案--------------------
虚继承就是多了个类似虚函数表的东西
至于为什么加上构造函数和析构函数会改变对象大小
坐等楼下。。
------解决方案--------------------
你得有一个函数指针指向虚函数!
------解决方案--------------------
你可以尝试输出来看看 到底里面是些什么东西
------解决方案--------------------
楼上说的对,是多了个虚基类的指针,这更构造函数和析构函数没有关心,sizeof只是求数据成员的大小
------解决方案--------------------
这些C++标准里没有做规定,所以编译器可以自己决定如何分配空间,可能为了优化,编译器在某种情况下把虚类指针和虚函数指针合在了一起。
------解决方案--------------------
你可以尝试着把内存模型输出来看看
------解决方案--------------------
我可以向你透露一点 虚继承情况下 第一个4字节存放的东西 我现在也搞不明白,第二个四字节开始存放子类的成员变量,接下来是虚函数指针和父类成员变量
你如果给子类加上了显式构造和析构 那么会多出一个4字节 存放了个0
至于为什么 我并不知道 但我研究的结果是这样
------解决方案--------------------
想起来听过一个视频,讲到这个多出来的4字节是什么东西, 回去找找再回复~~
------解决方案--------------------
跟有没有构造析构函数是没有关系的,跟虚函数有关系, 涉及到一个叫作“虚函数表”的东西。
可以参考 http://blog.csdn.net/haoel/article/details/1948051/
至于虚继承
可以参考 http://blog.csdn.net/jhj735412/article/details/7580498
在文章最后有几个类似你这种情况的例子,可以仔细看看。
------解决方案--------------------
虚继承的时候会给整个类增加一个叫做虚表的东西,用来动态的使用虚函数
可能是虚表的消耗,
------解决方案--------------------
建议楼主根本就不要浪费生命去研究C++内部的私有实现细节。
------解决方案--------------------
看了上面的解释我有点疑问 对象中确实是会有那么个指向虚表的指针 但它只是个指向个虚表的指针 要在上面增加什么东西的话也只可能在指向的那个虚表上面增加 为什么会影响到对象占用的内存大小呢
------解决方案--------------------
#include <iostream>
using namespace std;
class a
{
public:
a() {}
//~a(){}
int my;
virtual void draw()
{
cout<<"a draw"<<endl;
}
};
class test_b :public virtual a
{
public:
//test_b(){}
//~test_b(){}
public:
virtual void draw2()
{
cout<<"b draw"<<endl;
//return 0;
}
};
class test_b_: public virtual a
{
public:
test_b_(){};
//~test_b_(){};
virtual void draw()
{
cout<<" draw"<<endl;
//return 0;
}
};
class c:public test_b,public test_b_
{
public:
c(){}
~c(){}
virtual void draw()
{
cout<<"draw"<<endl;
//return 0;
}
};
int main()
{
cout<<sizeof(a)<<endl;
cout<<sizeof(test_b)<<endl;
cout<<sizeof(test_b_)<<endl;
cout<<sizeof(c)<<endl;
system("pause");
return 0;
}
在这里如果我在test_b里面加构造和析构函数的话sizeof得到的值就是16如果不加就是12,test_b_和c这两个类也是,只要加构造和析构就比不加多四个字节,为什么?虚继承到底都改变了些什么啊?
------解决方案--------------------
虚继承就是多了个类似虚函数表的东西
至于为什么加上构造函数和析构函数会改变对象大小
坐等楼下。。
------解决方案--------------------
你得有一个函数指针指向虚函数!
------解决方案--------------------
你可以尝试输出来看看 到底里面是些什么东西
------解决方案--------------------
楼上说的对,是多了个虚基类的指针,这更构造函数和析构函数没有关心,sizeof只是求数据成员的大小
------解决方案--------------------
这些C++标准里没有做规定,所以编译器可以自己决定如何分配空间,可能为了优化,编译器在某种情况下把虚类指针和虚函数指针合在了一起。
------解决方案--------------------
你可以尝试着把内存模型输出来看看
------解决方案--------------------
我可以向你透露一点 虚继承情况下 第一个4字节存放的东西 我现在也搞不明白,第二个四字节开始存放子类的成员变量,接下来是虚函数指针和父类成员变量
你如果给子类加上了显式构造和析构 那么会多出一个4字节 存放了个0
至于为什么 我并不知道 但我研究的结果是这样
------解决方案--------------------
想起来听过一个视频,讲到这个多出来的4字节是什么东西, 回去找找再回复~~
------解决方案--------------------
跟有没有构造析构函数是没有关系的,跟虚函数有关系, 涉及到一个叫作“虚函数表”的东西。
可以参考 http://blog.csdn.net/haoel/article/details/1948051/
至于虚继承
可以参考 http://blog.csdn.net/jhj735412/article/details/7580498
在文章最后有几个类似你这种情况的例子,可以仔细看看。
------解决方案--------------------
虚继承的时候会给整个类增加一个叫做虚表的东西,用来动态的使用虚函数
可能是虚表的消耗,
------解决方案--------------------
建议楼主根本就不要浪费生命去研究C++内部的私有实现细节。
------解决方案--------------------
看了上面的解释我有点疑问 对象中确实是会有那么个指向虚表的指针 但它只是个指向个虚表的指针 要在上面增加什么东西的话也只可能在指向的那个虚表上面增加 为什么会影响到对象占用的内存大小呢
------解决方案--------------------