隐藏

隐藏:子类对象优先考虑子类域自身成员(成员变量和成员函数)
  隐藏发生的主要原因,就是当子类有父类的同名成员时,子类对象访问该成员时,会发生冲突。所以编译器的处理方式是,优先考虑子类域中的自身成员。
即,子类对象访问某成员时,如ch.m_m 或者ch.f(),成员变量和成员函数都一样。编译器首先在子类域中检索,如果在子类域中找到该成员,则检索结束,返回该成员进行访问。如果在子类域中找不到该成员,则去父类域中检索。如果父类域中存在,则返回该成员进行访问,如果父类域中也不存在,则编译错误,该成员无效。
 ** 当父子类域都存在同一成员时,编译器优先在子类中检索,就算父类域中也存在该同名成员,也不会被检索到。因此,父类域中的该成员被子类域中的该同名成员隐藏,即访问时完全以为该成员不存在,如果想访问父类域中的该成员,只能通过显示调用的方式,即:ch.Father::m_m;**


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
class Father
{
public:
int f_a;
int f_b;
string f_c;
void ff1() {cout<<"father ff1"<<endl;}
};

class Childer:public Father
{
public:
int c_a;
int f_b;
int f_c;
void cf1() {cout<<"childer cf1"<<endl;}
void ff1() {cout<<"childer ff1"<<endl;}
};

int main()
{
Childer ch;

cout<<ch.c_a<<endl; //只在子类域中的成员变量
cout<<ch.f_b<<endl; //子类域和父类域都存在,优先访问子类域中的
cout<<ch.Father::f_b<<endl; //显示访问被隐藏的成员变量

cout<<"====================\n";

ch.cf1();
ch.ff1();
ch.Father::ff1();
}
  1. ch无法访问父类的f_bf_c。说明:名空间的隐藏只在乎名字是否相同,而不在乎类型是否相同
  2. ch.Father::ff1();必须通过显式调用才能访问到。说明:只是隐藏了,看不到了,而不代表没有

重载

重载:相同域的同名不同参函数
  重载必须是发生在同一个域中的两个同名不同形参之间的。如果一个在父类域一个在子类域,是不会存在重载的,属于隐藏的情况。调用时,只会在子类域中搜索,如果形参不符合,会认为没有该函数,而不会去父类域中搜索。

1
2
3
4
5
6
7
8
9
class A{
public:
void test(int i);
void test(double i);//overload
void test(int i, double j);//overload
void test(double i, int j);//overload
int test(int i); //错误,非重载。注意重载不关心函数返回类型。
};

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
//
// Created by 13467 on 2022/11/15.
//
#include <iostream>
#include <string>
#include <cstring>

using namespace std;

class Student {
int id = 10;//id在Undergraduated_Student中仍然是私有的,默认权限位private
void SetNickName(char *s) { strcpy(nickname, s); }

public:
char nickname[16];

void set_ID(int x) { id = x; }

void showInfo() { cout << nickname << ":" << id << endl; }

void showInfo(int x) { cout << x << endl; }

void getId() {
cout << "getId" << id << endl;
} // 通过继承基类的公有方法访问到基类的私有变量
protected:
int y = 7;
};

class Undergraduated_Student : public Student {
int dept_no{};//学院编号
public:
void setDeptNo(int x) { dept_no = x; }

// void showInfo(){cout << dept_no << ":" << nickname << endl;}
void set_ID(int x) {}

void SetNickName() {
cout << "changed" << endl;
} // 对基类的函数进行覆盖,并修改了访问权限
private:
using Student::nickname;//这样在才能修改可见性
void showInfo() {
cout << y << endl;
cout << dept_no << ":" << nickname << endl;
}
//新定义了一个private方法,父类对应方法被隐藏
};

int main() {
Undergraduated_Student *us = new Undergraduated_Student;
// cout << us->y;
us->SetNickName();
us->getId();
// us->showInfo(); 无法访问,通过隐藏父类的方法,修改了访问权限
us->Student::showInfo(10); // 被隐藏了,但是可以显式的使用对应的名空间进行访问
// us->showInfo(10); //error ,因为被子类的同名方法所隐藏了
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
//
// Created by 13467 on 2022/11/15.
//

#include <iostream>

using namespace std;

class A {
public:
virtual void f(int x = 110) = 0;

void f1() { cout << "base in A" << endl; }
};

class B : public A {
public:
void f(int x = 1) { cout << x << " in B" << endl; }

void f1() { cout << "override in B" << endl; }

void f1(int x) { cout << "overload_int" << endl; }

void f1(double x) { cout << "overload_double" << endl; }
};

class C : public A {
public:
inline C() {};

void f(int x = 75) { cout << x << " in C" << endl; }

void f1(int, double) { cout << " in C" << endl; }

};

int main() {
B b;
b.f1();
b.f1(10);
b.f1(100.5);
b.A::f1();
}
// override in B
// overload_int
// overload_double
// base in A