标签:lse 功能 类构造 父类 定义 注意 style 特殊 std
一,继承的基本概念
1.类与类之间的关系
2.继承的相关概念
万事万物皆有继承这个现象,所谓的继承就是一个类继承了另一个类的属性和方法,这个新的类包含了上一个类的属性和方法,被称为子类或者派生类,被继承的类称为父类或者基类。
3.继承的特点
4.继承的语法
二,继承中的访问控制
1.继承的访问控制方式
我们在一个类中可以对成员变量和成员函数进行访问控制,通过C++提供的三种权限修饰符实现。在子类继承父类时,C++提供的三种权限修饰符也可以在继承的时候使用,分别为公有继承,保护继承和私有继承。这三种不同的继承方式会改变子类对父类属性和方法的访问。
2.三种继承方式对子类访问的影响
3.父类如何设置子类的访问
三,继承中的构造和析构函数
1.父类的构造和析构
当创建一个对象和销毁一个对象时,对象的构造函数和析构函数会相应的被C++编译器调用。当在继承中,父类的构造和析构函数是如何在子类中进行调用的呢,C++规定我们在子类对象构造时,需要调用父类的构造函数完成对对继承而来的成员进行初始化,同理,在析构子类对象时,需要调用父类的析构函数对其继承而来的成员进行析构。
2.父类中的构造和析构执行顺序
3.继承中的构造函数示例
# include<iostream>
using namespace std;
class Parent
{
protected:
char * str;
public:
Parent(char * str)
{
if (str != NULL)
{
this->str = new char[strlen(str) + 1];
strcpy(this->str, str);
}
else {
this->str = NULL;
}
cout << "父类构造函数..." << endl;
}
~Parent()
{
if (this->str != NULL)
{
delete[] this->str;
this->str = NULL;
}
cout << "父类析构函数..." << endl;
}
};
class Child:public Parent
{
private:
char * name;
int age;
public:
/* 在构造子类对象时,调用父类的构造函数 */
Child():Parent(NULL)
{
this->name = NULL;
this->age = 0;
cout << "子类无参构造函数..." << endl;
}
/* 在构造子类对象时,调用父类的构造函数 */
Child(char * name,int age):Parent(name)
{
this->name = new char[strlen(name) + 1];
strcpy(this->name, name);
cout << "子类有参构造函数..." << endl;
}
~Child()
{
if (this->name != NULL)
{
delete[] this->name;
this->name = NULL;
}
cout << "子类析构函数..." << endl;
}
};
int main()
{
Child c1;
Child c2("王刚",22);
return 0;
}
输出结果:
4.继承与组合情况混搭下的构造析构函数调用顺序
5.继承和组合情况混搭情况下的代码演示
# include<iostream>
using namespace std;
/* 定义父类 */
class Parent
{
protected:
char * str;
public:
Parent(char * str)
{
if (str != NULL)
{
this->str = new char[strlen(str) + 1];
strcpy(this->str, str);
}
else {
this->str = NULL;
}
cout << "父类构造函数..." << endl;
}
~Parent()
{
if (this->str != NULL)
{
delete[] this->str;
this->str = NULL;
}
cout << "父类析构函数..." << endl;
}
};
/* 定义Object类 */
class Object
{
private:
int i;
public:
Object(int i)
{
this->i = i;
cout << "Object的构造函数..." << endl;
}
~Object()
{
cout << "Object的析构函数..." << endl;
}
};
/* 定义子类 */
class Child:public Parent
{
private:
/* 定义类成员变量 */
Object obj;
char * name;
int age;
public:
/* 在构造子类对象时,调用父类的构造函数和调用成员变量的构造函数 */
Child():Parent(NULL),obj(10)
{
this->name = NULL;
this->age = 0;
cout << "子类无参构造函数..." << endl;
}
/* 在构造子类对象时,调用父类的构造函数和调用成员变量的构造函数 */
Child(char * name,int age):Parent(name),obj(age)
{
this->name = new char[strlen(name) + 1];
strcpy(this->name, name);
cout << "子类有参构造函数..." << endl;
}
~Child()
{
if (this->name != NULL)
{
delete[] this->name;
this->name = NULL;
}
cout << "子类析构函数..." << endl;
}
};
int main()
{
Child c1;
Child c2("王刚",22);
return 0;
}
输出结果:
四,继承中的类型兼容性原则
1.继承中的同名成员
当在继承中,如果父类的成员和子类的成员属性名称相同,我们可以通过作用域操作符来显式的使用父类的成员,如果我们不使用作用域操作符,默认使用的是子类的成员属性。
2.继承中的同名成员演示
# include<iostream>
using namespace std;
class PP
{
public:
int i;
};
class CC:public PP
{
public:
int i;
public:
void test()
{
/* 使用父类的同名成员 */
PP::i = 10;
/* 使用子类的同名成员 */
i = 100;
}
void print()
{
cout << "父类:" << PP::i << "," << "子类:" << i << endl;
}
};
int main()
{
CC cc;
cc.test();
cc.print();
return 0;
}
3.类型兼容性原则
类型兼容性原则是指在需要父类对象的所有地方,都可以用公有继承的子类对象来替代。通过公有继承,子类获得了父类除构造和析构之外的所有属性和方法,这样子类就具有了父类的所有功能,凡是父类可以解决的问题,子类也一定可以解决。
4.类型兼容性原则可以替代的情况
5.类型兼容性原则示例
# include<iostream>
using namespace std;
/* 创建父类 */
class MyParent
{
protected:
char * name;
public:
MyParent()
{
name = "HelloWorld";
}
void print()
{
cout << "name = " << name << endl;
}
};
/* 创建子类 */
class MyChild:public MyParent
{
protected:
int i;
public:
MyChild()
{
i = 100;
name = "I am Child";
}
};
void main()
{
/* 定义子类对象 */
MyChild c;
/* 用子类对象当做父类对象使用 */
c.print();
/* 用子类对象初始化父类对象 */
MyParent p1 = c;
p1.print();
/* 父类指针直接指向子类对象 */
MyParent * p2 = &c;
p2->print();
/* 父类对象直接引用子类对象 */
MyParent& p3 = c;
p3.print();
}
6.继承中的static
7.继承中的static演示
# include<iostream>
using namespace std;
/* 父类 */
class MyP
{
public:
static int i;
};
/* 初始化静态成员 */
int MyP::i = 10;
/* 子类 */
class MyC:public MyP
{
public:
void test()
{
/* 直接访问 */
cout << "i = " << i << endl;
/* 通过父类访问 */
cout << "Myp::i = " << MyP::i << endl;
/* 通过子类访问 */
cout << "MyC::i = " << MyC::i << endl;
}
void add()
{
i++;
}
};
int main()
{
MyC c;
c.add();
c.test();
MyC c1;
c1.add();
c1.test();
/* 通过子类对象访问 */
c1.i = 100;
c1.test();
return 0;
}
五,多继承
1.C++中的多继承
所谓的多继承就是指一个子类可以继承多个父类,子类可以获取多个父类的属性和方法。这种继承方式是不被推荐的,但是C++还是添加了,事实证明,多继承增加了代码的复杂度,而且任何可以通过多继承解决的问题都可以通过单继承的方式解决。多继承和单继承的基本知识是相同的。不需要再阐述,主要讲解下面的不同的地方。
2,多继承中的构造和析构
和单继承类似,还是首先执行父类的构造函数,此时有多个构造函数,则按照继承时的父类顺序来执行相应父类的构造函数,析构函数与此相反。
3.多继承中的二义性
一个类A,它有两个子类B1和B2,然后类C多继承自B1和B2,此时如果我们使用类A里面的属性,则根据上面的多继承的构造和析构,发现此时的类A会被创造两个对象,一个是B1一个是B2,此时使用A里面的属性则会出现编译器无法知道是使用B1的还是B2的。因此C++为我们提供了虚继承这个概念,即B1和B2虚继承自A,则在构造A对象的时候,只创建一个A的对象。
4.多继承的二义性代码示例
此时如果去除virtual关键字,尝试一下会报错。
# include<iostream>
using namespace std;
/* 类B */
class B
{
public:
int a;
};
/* 虚继承自类B */
class B1 :virtual public B
{
};
/* 虚继承自类B */
class B2 :virtual public B
{
};
/* 继承自B1,B2 */
class C :public B1, public B2
{
};
void main()
{
C c;
c.B::a = 100;
cout << c.B::a << endl;
cout << c.B1::a << endl;
cout << c.B2::a << endl;
}
标签:lse 功能 类构造 父类 定义 注意 style 特殊 std
原文地址:https://www.cnblogs.com/ganxiang/p/13053075.html