请教两道C++虚继承和模板继承的内存变化的面试题

请教一下类的继承(虚继承和模板继承)导致内存变化的问题。

面试题一:假设现在有个基类叫Student学生,又有个派生类叫Graduate研究生(它比基类多了一个叫pay的成员,因为研究生一般有点工资):

class Student
{ 
    protected: //派生类可以访问protected成员 
        int num; string name; float score;
    public: 
        Student(int n, string m, float s) //构造函数 
        void display() {} //一般函数 
}; 
class Graduate: public Student //声明public继承
{
    private: 
        float pay; 
    public: 
        Student(int n, string m, float s, float p) //这样的构造函数正确吗?
        Graduate(int n, string m, float s, float p): Student(n,m,s), pay(p) {} //这样的构造函数正确吗?
        void display() {} //一般函数 
}; 
int main()
{ 
       Student stud1(1001,"Zhang",87);
      Graduate grad1(2001,"Wang",98, 1000);
      Student *pt = &stud1; //定义指向基类对象的指针变量pt 
      pt->display(); 
      pt = &grad1; //pt改为指向派生类对象…… 但是真的可以这样改变指向吗?
      pt->display(); //虽然pt指向派生类对象,但是运行结果没有派生类的数据成员pay!需要虚化。
}

问题1:构造函数Student(4个形参)和Graduate(依旧4个形参)的写法是否正确?

问题2:内存布局。基类Student比派生类Graduate少了一个叫pay的成员。那么是不是说,派生类Graduate的内存布局和基类Student一模一样,都是int n, string m, float s, void display()这样连续的内存挨在一起,只不过派生类Graduate多了一段由pay产生的内存?另外,函数void display()不同于int或者string等等数据成员,它又该占用多大内存呢?

问题3:虚函数的内存。为了解决上面的指针的问题,在Student类中声明display函数时,把函数void display()虚化成virtual void display()。那么是不是说,vtable这时候跳到了内存区间的第一位,内存布局从原来int n, string m, float s, void display()这样的布局,变成了虚化之后的vtable, int n, string m, float s这样的布局?vtable的内存是否已经包含了display()函数的内存呢?

面试题二:

template <typename T> class Foo
    {
    T tVar;
    public:
        Foo(T t): tVar(t) {}
    };
class Foo_Derived: public Foo<std::string> {};

int main()
    {
    Foo_Derived class_d; return 1;
    }

问题4:请问这个对于模板的继承,哪里错了?应该怎么改呢?

我在书上真没看到太多相关知识。恳请大家指点。谢谢了先!

阅读 3.3k
1 个回答

Student(int n, string m, float s, float p) //这样的构造函数正确吗?

这行是干嘛的?可以删掉.

Graduate(int n, string m, float s, float p): Student(n,m,s), pay(p) {} //这样的构造函数正确吗?

对.

pt = &grad1; //pt改为指向派生类对象…… 但是真的可以这样改变指向吗?

如果想要支持多态(即pt->display()调用的是对象grad1的结果),需要对函数进行虚化.+virtual

内存布局。基类Student比派生类Graduate少了一个叫pay的成员。那么是不是说,派生类Graduate的内存布局和基类Student一模一样,都是int n, string m, float s, void display()这样连续的内存挨在一起,只不过派生类Graduate多了一段由pay产生的内存?另外,函数void display()不同于int或者string等等数据成员,它又该占用多大内存呢?

这块的理解是不对的,成员函数不占用类实例的空间.

问题4:请问这个对于模板的继承,哪里错了?应该怎么改呢?

你定义的这个类对象 Foo_Derived 构造函数是需要入参. 你提供个空的构造函数,或者把当前的构造函数删了都行.

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题