文章目录
继承的方式
首先继承肯定拿不到父类中的private成员,只能拿public和protected
继承的三种方式:
- 公有继承,那么子类拿到的父类public和protected还放到自己的public和protected。
- 保护继承,子类拿到父类的都放到自己的protected。
- 私有继承,子类拿到父类的都放到自己的private。
#include <iostream>
using namespace std;
class Father
{
public:
int a;
protected:
int b;
private:
int c;
};
class Son : public Father
{
public:
void func()
{
cout << a << endl; // father中public但是是用protected方式继承来的。
cout << b << endl;
//cout << c << endl; 继承不到
}
};
int main()
{
Son son;
//son.a; 访问不了,因为在子类中是protected的。
}
一般继承都是public继承。protected和private实际中使用很少。
继承中构造和析构顺序
#include <iostream>
using namespace std;
class Father
{
public:
Father()
{
cout << "父类构造" << endl;
}
~Father()
{
cout << "父类析构" << endl;
}
};
class Son : protected Father
{
public:
Son()
{
cout << "子类构造" << endl;
}
~Son()
{
cout << "子类析构" << endl;
}
};
int main()
{
Son son;
}
/*
父类构造
子类构造
子类析构
父类析构
*/
当父类中没有无参构造
#include <iostream>
using namespace std;
class Father
{
public:
Father(int a)
{
cout << "父类构造" << endl;
}
~Father()
{
cout << "父类析构" << endl;
}
};
class Son : public Father
{
public:
//子类要先调用父类无参构造。但是父类没有无参构造,这时子类会报错
//解决方法:显示调用父类自定义的有参构造。
Son(int b): Father(b) //子类这个数直接也传给父类进行初始化
{
cout << "子类构造" << endl;
}
~Son()
{
cout << "子类析构" << endl;
}
};
int main()
{
Son son(5);
}
/*
父类构造
子类构造
子类析构
父类析构
*/
多继承
#include <iostream>
using namespace std;
class Father1
{
public:
int a;
};
class Father2
{
public:
int b;
};
class Son : public Father1, public Father2
{
public:
int c;
};
int main()
{
Son son;
son.a = 9;
son.b = 10;
}
多继承容易引发二义性的问题。比如两个父类定义了相同的变量.
解决方法:显示定义变量
#include <iostream>
using namespace std;
class Father1
{
public:
int a;
};
class Father2
{
public:
int a;
};
class Son : public Father1, public Father2
{
public:
int c;
};
int main()
{
Son son;
son.Father1::a = 9;
son.Father2::a = 10;
}
但是在实际使用中不建议使用多继承,因为容易引发二义性问题。
虚继承
C++虚继承作用
菱形继承问题。
class base
class derived1 : public base
class derived2 : public base
class derived3 : public derived1, public derived2
这个结构中,当base类中有一个成员变量,而derived3要使用这个变量时就会出现二义性问题。代码如下:
#include <iostream>
using namespace std;
class Parent
{
public:
int p; // p将会被所有的子类继承,也将是二义性的根源
Parent()
{
p = 10;
}
};
class Child1 : public Parent
{
public:
int c1;
Child1()
{
p = 1; // p在子类Child1中被赋值为12
c1 = 11;
}
};
class Child2 : public Parent
{
public:
int c2;
Child2()
{
p = 2; // p在子类Child2中被赋值为13
c2 = 22;
}
};
class GrandChild : public Child1, public Child2
{
public:
int grandchild;
// p显然也存在于GrandChild中,但是到底是1,还是2呢?这就产生了二义性
GrandChild()
{
grandchild = 3;
}
};
int main(void)
{
GrandChild *pGC = new GrandChild();
cout << pGC->p << endl;// 报错,出现二义性问题
return 0;
}
解决方法:
#include <iostream>
using namespace std;
class Parent
{
public:
int p; // p将会被所有的子类继承,也将是二义性的根源
Parent()
{
p = 10;
}
};
//利用虚继承,则child1为虚基类
class Child1 : virtual public Parent
{
public:
int c1;
Child1()
{
p = 1; // p在子类Child1中被赋值为12
c1 = 11;
}
};
class Child2 : virtual public Parent
{
public:
int c2;
Child2()
{
p = 2; // p在子类Child2中被赋值为13
c2 = 22;
}
};
// 继承了两个虚基类
class GrandChild : public Child1, public Child2
{
public:
int grandchild;
// p显然也存在于GrandChild中,但是到底是1,还是2呢?这就产生了二义性
GrandChild()
{
grandchild = 3;
}
};
int main(void)
{
GrandChild *pGC = new GrandChild();
cout << pGC->p << endl;//2 这时用的变量p是多继承中最后继承一个的值也就是child2中的
return 0;
}