c++类继承-小记

class A{
public:
    A(){print1();} //在构造函数里面调用virtual函数的做法本身不对,这里只为测试

    virtual void print1(){
        std::cout << "A print1" << std::endl;
    }
};

class B : public A{
public:
    virtual void print1(){
        std::cout << "B print1" << std::endl;
    }
};

class C{
public:
    char ch;
    virtual void print2(){
        std::cout <<"C print2"<<std::endl;
    }
};

class D : public A, public C
{
public:
    int cd;
    virtual void print1(){
        std::cout << "D print1" << std::endl;
    }

    virtual void print2(){
        std::cout << "D print2" << std::endl;
    }
};

int main()
{
    //Q1
    B b; // 输出 A print1

    //Q2
    std::cout << sizeof(D) <<std::endl; //16
    return 0;
}

/*
//A1:
输出A print1的原因是在class A的构造方法里面,对象b的构造方法内部还没有执行,
所以对象b还没有初始化也就没有虚函数表,在A的构造方法里面this指针就是A类型的,所以是调用A的print1

//A2
A的内存布局为
----------
__vfptr = 0x00c0ae48 const A::`vftable‘{for `A‘}
----------

C的内存布局
----------
__vfptr = 0x00c0abd8 const C::`vftable‘{for `C‘}
ch = 0xcccccccc
----------

D的内存布局
---------
A = {__vfptr = 0x00c0ae48 const D::`vftable‘{for `A‘} }
B = {__vfptr = 0x00c0abd8 const D::`vftable‘{for `C‘}
     ch = 0xcccccccc
    }
cd = 0xcccccccc
---------

所以 sizeof(D) = 4 + 8 + 4 (C的大小为8是因为内存还要对其)
*/
时间: 2024-07-30 13:52:45

c++类继承-小记的相关文章

scala学习手记13 - 类继承

在scala里,类继承有两点限制: 重写方法需要使用override关键字: 只有主构造函数才能往父类构造函数中传参数. 在java1.5中引入了override注解,但不强制使用.不过在scala中要想重写方法必须使用override关键字.如果确实重写了父类的方法又不使用override关键字的话,则会在编译时报错,提示没有使用override修饰符. scala的副构造函数必须调用主构造函数或是另一个副构造函数.只有在主构造函数中才能向父类的构造函数中传递数据.可以看出来主构造函数如同父类

sizeof 和类继承 虚继承 求类大小

代码: #include <iostream> using namespace std; /* class a{ float k; // 4字节 virtual void foo(){} //有一个4字节的指针指向自己的虚函数表 }; class b : virtual public a{ virtual void f(){} }; 有这样的一个指针vptr_b_a,这个指针叫虚类指针,也是四个字节:还要包括类a的字节数,所以类b的字节数就求出来了. 运行结果: 8 16 */ /* clas

JS中“类”继承和原型继承

类继承: 先用函数构造器创建了一个“类”Student,然后在Student原型上定义了一个方法sayHello,然后创建了一个"类“PrimaryStudent,用apply()初始化PrimaryStudent. 然后让PrimaryStudent的原型等于Student创建的对象,并把PrimaryStudent原型上的构造器指向当前”类“,即PrimaryStudent,注意红色加粗部分. 1 function Student(name){ 2 this.name = name; 3 }

javascript伪类继承修订版

原先文章中提到的伪类继承,超类的构造函数会被执行两次,所以效率上会有点问题,看了高级程序之后,发现原来还可以改进,只需要用一个函数来实现继承即可. function inherit(subClass, superClass) { function F() {} //创建临时构造函数 F.prototype = superClass.prototype //将超类的原型作为临时构造函数的原型 var prototype = new F() //实例化临时函数,到这里其实是把superClass复制

smartjs 0.2 OOP讲解 - Klass 类继承

SmartJS2.0加入OOP的功能.OOP包括klass与factory两个对象. Klass 类继承 与其他的类继承相比,smartjs使用了执行指针的概念(后面例子中会介绍),另外提供base基类和初始化控制的扩展功能. 首先来看看接口: var _klass = st.klass(name, prop, parent, config); //new _klass() 与 _klass()效果相同,实现了自初始化功能更 var obj = new _klass(); name : 类名 p

javascript类继承

function extend(subClass, superClass) { var f = function() {}; f.prototype = superClass.prototype; subClass.prototype = new f(); subClass.superClass = superClass.prototype; } var parent = function (name, age) { this._name = name; this._age = age; };

快学Scala 第十一课 (类继承)

类继承: class People { } class Emp extends People{ } 和Java一样,final的类不能被继承.final的字段和方法不能被override. 在Scala中重写一个非抽象方法必须使用override, 继承抽象方法前面加了override也没关系. abstract class Person { def say(s: String): Unit } class Worker extends Person{ override def say(s: S

修改tt模板让ADO.NET C# POCO Entity Generator With WCF Support 生成的实体类继承自定义基类

折腾几天记载一下,由于项目实际需要,从edmx生成的实体类能自动继承自定义的基类,这个基类不是从edmx文件中添加的Entityobject. 利用ADO.NET C# POCO Entity Generator With WCF Support生成的tt文件(比如model.tt)中找到 partial class partial class 修改tt模板让ADO.NET C# POCO Entity Generator With WCF Support 生成的实体类继承自定义基类

java类继承总结一 父类类型与子类类型之间的转化问题(转)

java类继承总结一 父类类型与子类类型之间的转化问题 本文将通过一个实例描述父类类型与子类类型之间的转化问题,这个很特殊的问题常常会导致一些潜在的危险,让你整整一个晚上都在调试程序以解决一个让人抓狂的java.lang.ArrayStoreException异常. 1. 子类数组的引用可以装换为超类数组的引用 2. 子类的引用child可以转换为父类的引用parent(这里假设parent是父类对象,child是子类对象),但却不可以通过 parent调用child的特有方法 class Em