C++
一、类
1、类就是C语言里面的结构体
2、函数放在结构体里面和外面,区别是需要用结构体变量(变量就是c++中的对象)调用,结构体大小没有发生改变
3、调用结构体函数时,就算一一个参数都不传递,汇编层面会传递一个结构体首地址的参数
4、封装就是将函数放在结构体里面
5、this指针是为了区分成员与参数同名,或者是获取结构体首地址
二、构造函数
1、函数(方法)不能写返回值
2、函数(方法)要与结构(类)名一样
3、初始化对象用的(创建一个变量(对象)就调用了)
4、构造函数可以有多个
5、重载函数判断依据是参数的个数和类型不一样就可以
#include "stdafx.h"
struct Test
{
int age;
int level;
//构造函数
Test(int age, int level)
{
this->age = age;
this->level = level;
}
//重载构造函数
Test()
{
}
//成员函数
void Print()
{
printf("%d %d",this->age,this->level);
}
};
int main(int argc, char* argv[])
{
Test p(1,2);
p.Print();
getchar();
return 0;
}
三、析构函数
1、只能有一个析构函数,不能重载
2、不能带任何参数
3、不能带返回值
4、主要用于清理工作
5、编译器不要求必须提供
#include "stdafx.h"
#include "malloc.h"
struct Person
{
int age;
int level;
char* arr;
Person(int age,int level)
{
printf("有参构造函数执行了...\n");
this->age = age;
this->level = level;
arr = (char*)malloc(1024);
}
~Person()
{
printf("析构函数执行了...");
free(arr);
arr = NULL;
}
void Print()
{
printf("%d-%d\n",age,level);
}
};
void Test()
{
Person p(1,2);
p.Print();
}
int main(int argc, char* argv[])
{
Test();
getchar();
return 0;
}
四、继承
1、继承就是数据的复制
2、减少重复代码的编写
3、Person 称为父类或者基类
4、Teacher、Student称为子类或者派生类
5、t和s可以称为对象或者实例
6、可以用父类指针指向子类的对象(但是不能访问子类成员)
#include "stdafx.h"
struct Person
{
int age;
int sex;
};
struct Teacher:Person
{
int level;
int classId;
};
struct Student:Person
{
int code;
int score;
};
void Test()
{
Student t;
t.age = 1;
t.sex = 2;
t.code = 3;
t.score = 4;
Person* pt = &t;
printf("%d\n",pt->age);
}
int main(int argc, char* argv[])
{
Test();
getchar();
return 0;
}
五、多层继承
不推荐写法
#include "stdafx.h"
struct X
{
int a;
int b;
};
struct Y:X
{
int a;
int d;
};
struct Z:Y
{
int e;
int f;
};
void Test()
{
Z z;
z.X::a = 1;
z.b = 2;
z.Y::a = 3;
z.d = 4;
z.e = 5;
z.f = 6;
printf("%d\n",sizeof(z));
}
int main(int argc, char* argv[])
{
Test();
getchar();
return 0;
}
六、多重继承
不推荐写法
#include "stdafx.h"
struct X
{
int a;
int b;
};
struct Y
{
int a;
int d;
};
struct Z:X,Y
{
int e;
int f;
};
void Test()
{
Z z;
z.X::a = 1;
z.b = 2;
z.Y::a = 3;
z.d = 4;
z.e = 5;
z.f = 6;
printf("%d\n",sizeof(z));
}
int main(int argc, char* argv[])
{
Test();
getchar();
return 0;
}
七、public和private
不能编译,因为私有属性不能直接调用,需要在结构体内调用
#include "stdafx.h"
struct Test
{
private:
int x;
public:
int y;
};
int main(int argc, char* argv[])
{
Test p;
p.x = 10;
return 0;
}
八、使用指针调用私有属性
-
private修饰的成员与普通的成员没有区别 只是编译器会检测.
-
private修饰的成员只要自己的其他成员才能访问
#include "stdafx.h"
struct Test
{
private:
int x;
public:
int y;
void Init(int x,int y)
{
this->x = x;
this->y = y;
}
};
int main(int argc, char* argv[])
{
Test t;
t.Init(1,2);
int* p = (int*)&t;
int n = *p;
int m = *(p+1);
printf("%d %d\n",n,m);
getchar();
return 0;
}
九、class与struct的区别
1、class 默认是private,必须手动添加public才能访问
2、struct默认是public,直接就可以访问
3、class 继承需要手动添加如何继承,不添加默认是private继承,手动添加public,原来是public继承就是public,原来继承private,继承就是private
4、struct继承直接可以访问
十、私有属性继承
继承,相当于将父类的属性复制一份,但是编译器不允许我们使用私有的,但我们可以通过指针来调用
#include "stdafx.h"
class Base
{
public:
Base()
{
x = 11;
y = 12;
}
private:
int x;
int y;
};
class Sub:Base
{
public:
int a;
int b;
};
int main(int argc, char* argv[])
{
Sub sub;
sub.a = 1;
sub.b = 2;
int* p = (int*)⊂
printf("%d\n",sizeof(sub));
printf("%d\n",*(p+0));
printf("%d\n",*(p+1));
printf("%d\n",*(p+2));
printf("%d\n",*(p+3));
getchar();
return 0;
}
十一、虚函数表
1、加了virtual,会多出4字节在this指针里面存着
2、this指针储存的是虚函数表
#include "stdafx.h"
class Base
{
public:
int x;
int y;
Base()
{
this->x = 1;
this->y = 2;
}
void Function_1()
{
printf("Function_1...\n");
}
virtual void Function_2()
{
printf("Function_2...\n");
}
};
int main(int argc, char* argv[])
{
Base p;
typedef void(*pFunction)(void);
pFunction pf;
pf = (pFunction)(*(int*)(*(int*)&p));
pf();
getchar();
return 0;
}
3、单继承无函数覆盖
4、单继承有函数覆盖
子类会重写
#include "stdafx.h"
class Base
{
public:
virtual void Function_1()
{
printf("Base:Function_1...\n");
}
virtual void Function_2()
{
printf("Base:Function_2...\n");
}
virtual void Function_3()
{
printf("Base:Function_3...\n");
}
};
class Sub:Base
{
public:
virtual void Function_1()
{
printf("Sub:Function_1...\n");
}
virtual void Function_2()
{
printf("Sub:Function_2...\n");
}
virtual void Function_6()
{
printf("Sub:Function_6...\n");
}
};
int main(int argc, char* argv[])
{
Sub p;
printf("%x\n",&p);
typedef void(*pFunction)();
pFunction pf;
for(int i=0;i<4;i++)
{
pf = (pFunction)*((int*)(*(int*)&p)+i);
pf();
}
getchar();
return 0;
}
5、多继承无函数覆盖
6、多继承有函数覆盖
7、多态(动态绑定)
#include "stdafx.h"
class Base
{
public:
int x;
public:
Base()
{
x = 100;
}
void Function_1()
{
printf("Base:Function_1...\n");
}
virtual void Function_2()
{
printf("Base:Function_2...virtual\n");
}
};
class Sub:public Base
{
public:
int x;
public:
Sub()
{
x = 200;
}
void Function_1()
{
printf("Sub:Function_1...\n");
}
virtual void Function_2()
{
printf("Sub:Function_2...virtual\n");
}
};
void TestBound(Base* pb)
{
int n = pb->x;
printf("%d\n",n);
pb->Function_1(); //函数调用
pb->Function_2();
}
int main(int argc, char* argv[])
{
Sub b;
TestBound(&b);
getchar();
return 0;
}
十二、模板
1、模板定义
#include "stdafx.h"
template<class T>
void add(T a,T b)
{
printf("%d",a+b);
}
int main(int argc, char* argv[])
{
char a = 5;
char b = 6;
add(a,b);
getchar();
return 0;
}
2、类的模板定义
#include "stdafx.h"
template<class T>
class Test
{
public:
void add(T a)
{
printf("++++%d",a);
}
};
int main(int argc, char* argv[])
{
char a = 5;
Test<int> p;
p.add(10);
getchar();
return 0;
}