继承
被继承的叫做父类或者基类,继承的类叫派生类或者子类。继承时需要标明启程权限。父类的私有权限变量子类不能访问,可以访问protected权限。
#include <iostream>
using namespace std;
class TestA
{
private:
int a; //只能在类的内部访问
protected:
int b;
public:
int c;
};
//私有继承
class TestB : private TestA
{
/*
private:
int a;
private:
int b;
private:
int c;
*/
public:
void test()
{
//a++; 在TestA中, a是私有成员变量, 不能访问
b++;
c++;
}
};
class TestC : protected TestA//保护继承
{
/*
int a;
protected:
int b;
int c;
*/
public:
void test()
{
//a++;
b++;
c++;
}
};
//公有继承
class TestD : public TestA
{
/*
int a;
procected;
int b;
public:
int c;
*/
public:
void test()
{
//a++;
b++;
c++;
}
};
int main()
{
TestB tb;
//tb.b;
//tb.c;
TestD td;
//td.b;
td.c;
return 0;
}
继承后父类的变量储存在子类本身变量的前面。
#include <iostream>
using namespace std;
class Person
{
public:
int age;
};
class Student : public Person
{
public:
int id;
};
int main()
{
Student s;
cout << sizeof(s) << endl;
cout << &s <<endl;//派生类的内存布局, 先存放基类成员, 在存放派生类
cout << &s.age << endl;//继承的变量在前面
cout << &s.id << endl;
return 0;
}
在继承中,子类会调用父类
先构造父类, 在构造成员, 最后构造自己 ;析构的顺序跟构造是相反的
1、子类对象在创建时会首先调用父类的构造函数 2、父类构造函数执行完执行子类;3、父类构造函数有参数时可以通过初始化列表传参;4、派生类不能调用间接基类的构造函数
#include <iostream>
#include <cstring>
using namespace std;
class Person //父类或者基类
{
protected: //保护权限: 类的内部可以访问, 派生类内部可以访问, 类的外部都不能访问
char name[32];
int age;
public:
/* Person()
{
cout << "Person构造函数" << endl;
strcpy(name, "aaa");
age = 20;
}*/
Person(const char *n, int a)
{
cout << "" << endl;
strcpy(name, n);
age = a;
}
~Person()
{
cout << "Person析构函数" << endl;
}
};
class Data
{
protected:
int year;
int mouth;
int day;
public:
Data(int y, int m, int d)
{
cout << "Data有参构造函数" << endl;
year = y;
mouth = m;
day = d;
}
~Data()
{
cout << "Data析构函数" << endl;
}
};
class Student : public Person //子类或者派生类 public继承权限
{
private:
int id;
Data birth; //先构造父类, 在构造成员, 最后构造自己
public:
Student(int i) : Person("aaa", 23) , birth(1, 1, 1) //当基类没有提供无参构造函数的时候, 派生类需要通过对象初始化列表来传参
{
cout << "Student构造函数" << endl;
this->id = i;
}
~Student()
{
cout << "Student析构函数" << endl;
}
void show()
{
cout << name << " " << age << " " << id << endl;
//cout << id << endl;
}
};
int main()
{
Student s(1); //创建派生类对象, 会先调用基类构造函数,来初始化继承来的成员
s.show();
return 0; //析构的顺序跟构造是相反的
}
同名通常调用派生类,基类被隐藏了。通过作用域调用
通常不存在重载情况,只要同名父类被覆盖。
#include <iostream>
using namespace std;
class TestA
{
private:
int a;
public:
void show()
{
cout << "this is TestA" << endl;
}
};
class TestB : public TestA
{
private:
int a;
public:
void show()
{
cout << "this is TestB" << endl;
}
};
int main()
{
TestB tb;
cout << sizeof(tb) << endl;
tb.TestA::show();//同名默认调用派生类, 想调用基类加上::
tb.show();
return 0;
}
static静态成员变量在子类和父类是公用的。
#include <iostream>
using namespace std;
class Person
{
public:
static int count;
public:
Person()
{
count++;
}
};
int Person::count = 0;
class Student : public Person
{
};
int main()
{
Student s1;
Student s2;
Student s3;
Person p1;
Person p2;
Person p3;
cout << Person::count << endl; //派生类和基类共享一个静态成员变量
cout << Student::count << endl;
return 0;
}