成员权限问题:
public公有级别能被外界直接访问,**private只能被在类内部和类成员函数访问,**不能被外界直接访问。子类继承父类后,便拥有了父类的所有属性,
//单继承问题,继承不会扩大成员权限,只会保持不变或者变小
1-私有属性的继承
#include
using namespace std;
class A
{
private:
int m_a=4;
public:
void print(){
cout<<"m_a:"<<m_a<<endl;
};
};
class B:public A
{
private:
int m_b;
};
int main()
{
B b;
b.print();
}
1-类A中的所有数据成员都会被类B继承(也就是类B有一份类A的拷贝本),尽管类A中的m_a是私有属性,但类B中依旧会有一份(只是无法直接访问)。
2-子类继承的私有属性无法直接访问,但可以间接通过调用父类的get方法访问
2-保护属性的继承
#include
#include
using namespace std;
class Parent
{
protected: //将原来的private属性改为protect属性
int m_value1;
void fun1()
{
cout << "Parent::fun1()" << endl;
}
public:
int m_value2;
void fun2()
{
cout << "Parent::fun2()" << endl;
}
};
class Child : public Parent
{
public:
void ChildFun()
{
m_value1 = 10; //子类中直接访问父类的保护成员变量
fun1(); //子类中直接访问父类的保护成员函数
m_value2 = 20; //子类中直接访问父类的公有成员变量
fun2(); //子类中直接访问父类的公有成员变量
}
};
int main()
{
Child C;
C.ChildFun();
system("pause");
}
-protect修饰的成员不能被外界所访问 protect修饰的成员能被子类直接访问
//多继承出现的同名函数问题()
如果某派生类的多个基类拥有同名的成员,同时,派生类又新增这样的同名成员,在这种情况下,派生类成员将因此拥有所有基类的同名成员。使用“对象名.成员名”或“对象指针名->成员名”方式可以唯一标识和访问派生类新增成员,基类的同名成员也可以使用基类名或作用域分辨符访问。
样例一 这里只演示了继承一个父类的情况(继承多个父类的情况将在多态那里介绍)
// 多继承同名函数问题(多态问题)
#include
using namespace std;
class BaseClass
{
public:
// virtual void fn1() {
// cout << "调用BaseClass的成员函数fn1aa" << endl;
// }
// virtual void fn2() {
// cout << "调用BaseClass的成员函数fn2bb" << endl;
// }
void fn1()
{
cout << "调用BaseClass的成员函数fn1aa" << endl;
}
void fn2()
{
cout << "调用BaseClass的成员函数fn2bb" << endl;
}
};
class DerivedClass : public BaseClass
{
public:
void fn1()
{
cout << "调用DerivedClass的成员函数fn1cc" << endl;
}
void fn2()
{
cout << "调用DerivedClass的成员函数fn2dd" << endl;
}
};
int main()
{
// 1-通过类名限定
DerivedClass p1;
p1.BaseClass::fn1();
p1.BaseClass::fn2();
p1.DerivedClass::fn1();
p1.DerivedClass::fn2();
cout << "********************" << endl;
// 2-通过创建对象
// a-正常指针
DerivedClass *ptr = new DerivedClass; //本质是调用构造函数
ptr->fn1();
ptr->fn2();
BaseClass *pptr = new BaseClass;
pptr->fn1();
pptr->fn2();
cout << "*****************" << endl;
// b-父类指针指向子类对象
//若基类的函数没加virtual 则看指针类型
//若基类的函数加了virtual 则看调用对象
BaseClass *Bptr = new DerivedClass;
Bptr->fn1();
Bptr->fn2();
}
#include
using namespace std;
class father
{
int age;
public:
int height;
father(int age = 0, int height = 0);
void print();
};
father::father(int age, int height) : age(age), height(height){};
void father::print()
{
cout << "height: " << this->height << "\t"
<< "age: " << this->age << endl;
};
class son : public father
{
public:
son(int s_age, int s_height) : father(s_age ,s_height)
{
print();
};
};
int main()
{
son s(11, 22);
}
1-父类数据成员的初始化一定依赖父类的构造函数;
3-先调用父类的构造函数,再调用子类的构造函数
2-子类的构造函数一定需要调用父类的构造函数;(如果没有显式调用,那父类的构造函数一定是默认的无参构造函数)
关于上面的第二点:如下:
#include
using namespace std;
class father
{
int age;
public:
int height;
father()
{
cout << "调用父类的构造函数aa" << endl;
};
};
class son : public father
{
private:
int age;
public:
son(int age)
{
this->age = age;
cout<<this->age<<endl;
};
// son() :father()// 其实就是隐式调用父类构造,也可以写成显式调用。
// {
// };
};
int main()
{
son s(11);
}
//继承的时候出现的问题
#include
using namespace std;
class father
{
int age;
public:
int height;
father(int age = 0, int height = 0);
void print();
};
father::father(int age, int height) : age(age), height(height){};
void father::print()
{
cout << "height: " << this->height << "\t"
<< "age: " << this->age << endl;
};
class son : public father
{
public:
son(int s_age, int s_height) : father(s_age), height(s_height){
print();
};
};
int main()
{
son s(11, 22);
}
报错:class ‘son’ does not have any field named ‘height’
原因: 子类的参数初始化列表只能初始化自己的东西; 要初始化父类继承过来的东西,只能传给父类的构造函数,在父类的构造函数里初始化。 或者在子类构造函数体内初始化。
所以将子类的构造函数改为:
son(int s_age, int s_height) : father(s_age),{
height= s_height;
print();
};