1. 类与类之间的关系
class A
{
  public:
    int a;
    void funcA()
    {}
}
包含:
class B
{
  public:
    void funcB(){}
    A a;
}
//如果类B有类A的成员变量,那么B has A,类B依赖于类A
使用:
class C
{
  public:
    void funC(A *a)
    {
    }
}
//C的成员方法需要A的形参,C use A

*B与A的耦合度比C要高。
//
继承:
class D:public A
{
  void funcD()
  {

  }
  D(int a):A(a) //与C#不同的地方,C#是D(int a):base(a),可能是C++有多重继承的原因
  {
  //..
  }
}
*D si A,耦合度最高。
//为什么要写public 呢?应该是确定能否通过D来访问A的成员???

has A,use A, is A;

2.
A->B->C
A->B1->C1
B->D
B1->D
D是多继承

3.类的继承方式

这是和C#不同的地方,C#没有继承方式,继承就是继承了,就算有,C#都是public继承, A中的成员的“外部和继承可访问性”,继承后还是一样。

C++通过继承方式,限制了继承后,改变了原来A“对外和继承的可访问性”。

更多是private和protect的继承方式,对原来A中public的影响最大

*一般用public就行了,其他继承方式不建议使用。

4. 类的兼容原则
  class A;
  class Aplus:public A;
  int main()
  {
    Aplus ap;
    A a=ap;
  }
//跟C#类似,能里氏替换,c#子类引用变量能赋值给父类引用变量;
//C++因为子类有父类的所有东西,所以能给父类的所有字段初始化;
//父类指针可以指向子类对象
//父类引用可以引用子类对象
//左父=右子(右子赋值(=号操作符)给左父,右子初始化左父(构造函数))
//子类能够满足父类指针、引用、变量的全部需求。反之不行。

5. 子类构造析构
构造函数,跟C#一样,会先调用父类的构造函数

6. 继承中,子类的成员和父类成员有重名:
子类内部
void func()
{
  this->a=1;
  A::a=1;//注意,这里要和使用静态的成员区分。
}
//一般都避免这样
//C++的继承其实是很粗暴的,内存的开辟直接堆上去,不管重不重名,有就堆上去。
//C#中,子类的字段不能和父类同名,属性也是,如果非要同名,要加public new int Age{ get;set;}

7.
class A
{
  public:
  static int a;//静态变量在静态区,继承方式是影响不了其访问性
}
int A::a=100;//静态变量初始化
//
int main()
{
  A a;
  cout<<a.a<<endl;
}

8. 多继承
//
class Furniture
{
  public : int price;
}
class Sofa:public Furniture;
class Bed:public Furniture;
class SofaBed:public Bed,public Sofa;
//
那SofaBed就有两个price空间的大小了(c++粗暴的堆上去),那只能
int main()
{
  SofaBed sb;
  sb.Bed::price=100;
  sb.Sofa::price=200;
}
//这是和C#不同的地方,C#没有多继承

9. 虚继承 (一般很少这样做)
**要不想这样子,给两个price赋值,那么只能:

  class Sofa:vitual public Furniture;//加virtual
  class Bed:vitual public Furniture;//加virtual
  class SofaBed:public Bed,public Sofa;//不变

####出现棱形继承#####
**父类继承爷爷类的时候加virtual
**virtual继承,只是为了开辟“爷类”的字段一次
#区别开C#中的virtual方法,C#中virtual只是用来标记方法,能被子类重新,在以父类或者子类引用的方式调用时,均会执行子类的重写的方法。

10. C++中的虚方法(重要)
class A {
  public:
    function()
    {
      //...
    }
};
class Aplus:public A
{
  public:
    function()
    {
      //...
    }
}
//
int main()
{
  A *a=new Aplus();//左父右子
  a->Function();//这里是调用了A的fuction,不写成虚方法,就执行指针类型的funtion;
}
(这种又叫重定义,调用以A的指针调用function,那么执行A的function;以Aplus的指针调用function,那么执行Aplus的function。)
//这里又和C#不同了,同名方法没有标记为virtual都可以继承。
//C++是父类型指针变量,指向子类对象,能调用子类方法。
***如果想象C#一样,用父类变量引用子类对象,依然可以执行子类的方法。
解决办法:
class A {
  public:
    vitual function()//虚方法
    {
      //...
    }
};
//这里又和C#不同了,子类不需要在方法前写override
****************但是,习惯上也在子类的方法前加virtual,做一个标识作用,就当做C#中的override****************
//在.cpp文件中,实现虚方法,就不需要加virtual了。

11. 虚析构函数(重要)
防止在使用“左父-右子”的父指针 delete father,如果不标记析构函数为virtual(原因见下),只能析构父类的空间。子类写成virtual析构,能两个析构都调用,不用自己再在子析构中,显式调用父析构。
***特别是用工厂方法new对象时,较为要紧*********
*在正常析构子类对象时,父类对象能自动析构

***********继承也要注意父析构函数标记virtual**********

13. vtpr指针(重要)。
vtpr指针,是指向虚函数表的指针。
例如:A中有virtual fun1(); Aplus重写;
fun1会放到A的虚函数表;fun1会放到Aplus的虚函数表;

  A a=new Aplus();
  a->fun1();
编译器发现fun1()是虚的,应该会额外标记(重要步骤)。在运行的时候,vtpr指针会去虚函数表找fun1的函数,因为a实质上是Aplus,所以实质上是去找Aplus的虚函数表。
//所以,如果A的fun1没标记为virtual,那么编译自然不会额外标记了,在运行时就只按照A类查找普通的函数表;
//小知识,同样的类,有函数加了virtual,那么sizeof(A)会莫名增大,因为多了vtpr指针的大小。
//不要在父类构造函数中调用virtual函数,否则子类vtpr指针还没初始化好,调的依然是父类的函数,vtpr指针是随着各个父类的构造函数,不断变换指向,直到最后的子类的。

14. 指针步长
A array[] = {Aplus(0),{Aplus(1),{Aplus(2)};//相当于C#A[] array = {new Aplus(0),..};
可以使用array代表是指向第一个元素的地址;
array++可以指向第二个元素;但是,要注意的是,array++是按A的内存大小,往下跳的,如果Aplus所占用的大小大于A,那么array++会跳到一个错误的位置。

15. 纯虚函数,抽象类(C++没有C#中的接口,但是有纯虚函数)
class shape{
  public:
  double height;
  double weight;
  virtual int func()=0;//=0只是一个语法,标记为纯虚函数。并不是返回值
  shape(){}
  virtual ~shape(){}//抽象类最好提供一下虚析构
}
//如果一个类有纯虚函数,那么就是抽象类,不管有没有普通函数。
//跟C#一样,抽象类不能实例化。
//跟C#一样,抽象类能继承抽象类。
/ /跟C#不一样,C#的抽象类必须写成abstract,而且可以写virtual函数,virtual函数能有实现,反而抽象函数,要标记开abstract

class A:public Interface;

最新文章

  1. hadoop fs -ls no such file or directory
  2. 安装OS X虚拟机错误vcpu-0:VERIFY vmcore/vmm/main/physMem_monitor.c:1123
  3. hmm
  4. css选择器总结
  5. shFlags简介
  6. memcached与.NET的融合使用(一)
  7. centos dhcp网络设置
  8. Spring事务:传播行为与隔离级别
  9. 创建动态组-以OU为单位
  10. 优化UITableViewCell高度计算的那些事(RunLoop)
  11. matlab怎么同时显示imshow 两幅图片
  12. iOS: 学习笔记, 透过Boolean看Swift(译自: https://developer.apple.com/swift/blog/ Aug 5, 2014 Boolean)
  13. linux学习笔记之sudo
  14. 《HTML5权威指南》
  15. 【2】docker 与UFW
  16. DRAM Memory Rank知识
  17. Everything开机自启
  18. postman接口测试系列:接口参数化和参数的传递
  19. 【CentOS】PostgreSQL安装与设定
  20. maven本地库与私服比对,查找缺失jar包

热门文章

  1. 1. SOFAJRaft源码分析— SOFAJRaft启动时做了什么?
  2. 【SQL】sql统计不同类别的不同状态的数目
  3. 阿里云VS腾讯云 谁才是中国未来的云计算之王?
  4. Golang的反射reflect深入理解和示例
  5. python编程基础之二十三
  6. e课表项目第二次冲刺周期第八天
  7. Jackson日期转换少一天
  8. What is neural network?
  9. 像艺术家一样思考 Think Like an Artist
  10. [Luogu1313][NOIP2011提高组]计算系数