函数名相同,函数参数列表不同,和返回值无关,和const有关
成员函数被重载的特征:
(1)相同的范围(在同一个类中);
(2)函数名字相同;
(3)参数不同;
(4) virtual关键字可有可无。
覆盖是指派生类函数覆盖基类函数,特征是:
(1)不同的范围(分别位于派生类与基类);
(2)函数名字相同;
(3)参数相同;
(4)基类函数必须有virtual关键字。
派生类的成员函数和基类的函数同名同参,则将基类的函数隐藏。
这里“隐藏”是指派生类的函数屏蔽了与其同名的基类函数,规则如下:
(1)如果派生类的函数与基类的函数同名,但是参数不同。
此时,不论有无 virtual关键字,基类的函数将被隐藏(注意别与重载混淆)。
(2)如果派生类的函数与基类的函数同名,并且参数也相同,但是基类函数没有virtual关键字。
此时,基类的函数被隐藏(注意别与覆盖混淆)。
1、继承关系的类
2、父子类的同名同参函数不能为虚
class A
{
public:
void print() { cout << "A::print" << endl; }
};
/*
隐藏:派生类的成员函数和基类的函数同名同参,则将基类的函数隐藏
*/
class B :public A
{
public:
//print将派生下来的A的print隐藏了
void print()
{
cout << "B::print" << endl;
}
};
void main()
{
A a;
B b;
a.print();
b.print();
}
运行结果:
class A
{
public:
void print() { cout << "A::print" << endl; }
protected:
int m_i;
};
/*
隐藏:派生类的成员函数和基类的函数同名同参,则将基类的函数隐藏
*/
class B :public A
{
public:
//print将派生下来的A的print隐藏了
void print()
{
cout << "B::print" << endl;
cout << m_i << " " << A::m_i << endl;
}
void set() { m_i = 10; A::m_i = 20; }
protected:
int m_i;
};
void main()
{
A a;
B b;
a.print();
b.set();
b.A::print();
b.print();
cout << sizeof(B) << endl;
}
运行结果:
对于以下代码,无法正常实现
class Person
{
public:
Person(){cout << "Person()" <<endl;}
Person(const char *name,char sex,int age):m_sex(sex),m_age(age)
{
m_name = new char[strlen(name) + 1];
strcpy_s(m_name,strlen(name) +1,name);
}
void print()
{
cout << m_name <<" "<< m_sex <<" "<< m_age <<" ";
}
private:
char *m_name;
char m_sex;
int m_age;
};
class Student:public Person
{
public:
Student(){cout << "Student()" <<endl;}
Student(int num,const char *name,char sex,int age,int score):Person(name,sex,age),m_num(num),m_score(score){}
void print()
{
cout << m_num << " ";
Person::print();
cout << m_score << endl;
}
private:
int m_num;
int m_score;
};
void main()
{
Student s;
Student s1(1001,"yasuo",'f',21);
s.print();//error,出错点
s1.print();
}
Person类和Student类的内存布局:
而主程序定义了无参对象s和有参对象s1.
而无参对象s,构造时,没能为其中的指针char *m_name;
开辟空间,
就例如下述代码:
void main()
{
int *p;
cout << p << endl;//erroe,其没有指向合法的内存空间
}
有无参构造,并且有指针数据成员。需要在无参构造函数里为其开辟空间,一个空间作为占位符。
class Person
{
public:
//Person():m_sex('f'),m_age(20)
Person()
{
m_name = new char[1];
*m_name = '\0';
}
Person(const char *name,char sex,int age):m_sex(sex),m_age(age)
{
m_name = new char[strlen(name) + 1];
strcpy_s(m_name,strlen(name) +1,name);
}
~Person()
{
if(m_name != NULL)
{
delete[]m_name;
m_name = NULL;
}
}
private:
char *m_name;
char m_sex;
int m_age;
};
示例代码:
class Person
{
public:
Person():m_sex('f'),m_age(20)
{
m_name = new char[1];
*m_name = '\0';
cout << "Person()" << endl;
}
Person(const char* name, char sex, int age):m_sex(sex),m_age(age)
{
m_name = new char[strlen(name) + 1];
strcpy_s(m_name, strlen(name) + 1, name);
}
Person(Person& p) :m_sex(p.m_sex), m_age(p.m_age)//拷贝构造函数
{
m_name = new char[strlen(p.m_name) + 1];
strcpy_s(m_name, strlen(p.m_name) + 1, p.m_name);
}
Person& operator=(Person& p)//赋值运算符重载
{
if (this == &p)
return *this;
delete[]m_name;
m_name = new char[strlen(p.m_name) + 1];
strcpy_s(m_name, strlen(p.m_name) + 1, p.m_name);
m_sex = p.m_sex;
m_age = p.m_age;
return *this;
}
void print()
{
cout << m_name << " " << m_sex << " " << m_age << " ";
}
~Person()
{
if (m_name != NULL)
{
delete[]m_name;
m_name = NULL;
}
}
private:
char* m_name;
char m_sex;
int m_age;
};
class Student :public Person
{
public:
Student():m_num(0),m_score(0) { cout << "Student()" << endl; }
Student(int num, const char* name, char sex, int age, int score):m_num(num),Person(name,sex,age),m_score(score) {}
void print()
{
cout << m_num << " ";
Person::print();
cout << m_score << endl;
}
Student(Student& s) :Person(s), m_num(s.m_num), m_score(s.m_score) {}//拷贝构造函数
Student& operator=(Student& s)//赋值运算符重载
{
if (this == &s)
return *this;
Person::operator=(s);
m_num = s.m_num;
m_score = s.m_score;
return *this;
}
private:
int m_num;
int m_score;
};
void main()
{
Student s;
Student s1(1001, "zhangsan", 'f', 20, 78);
s.print();
s1.print();
Student s2(s1);//调用拷贝构造函数
s2.print();
s = s1;//调用赋值运算符重载
s.print();
}
运行结果:
基类继承后,子类也有对静态数据成员的使用权,是共享的。
但不占类内空间。
示例代码:
class Person
{
public:
Person(int num = 1000) :m_num(num) {}
void print()
{
cout << "count = " << m_count << endl;
}
protected:
int m_num;
static int m_count;//静态数据成员
};
int Person::m_count;//外部二次声明,对该静态成员进行初始化
//三个继承类:
class Student :public Person
{
public:
Student(int num, const char* job) :Person(num)
{
m_job = new char[strlen(job) + 1];
strcpy_s(m_job, strlen(job) + 1, job);
m_count++;
}
private:
char* m_job;
};
class Teacher :public Person
{
public:
Teacher(int num,const char*job):Person(num)
{
m_job = new char[strlen(job) + 1];
strcpy_s(m_job, strlen(job) + 1, job);
m_count++;
}
private:
char* m_job;
};
class Worker :public Person
{
public:
Worker(int num,const char*job) :Person(num)
{
m_job = new char[strlen(job) + 1];
strcpy_s(m_job, strlen(job) + 1, job);
m_count++;
}
private:
char* m_job;
};
void main()
{
Student s(1001, "student");
Teacher t(1002, "teacher");
Worker w(1003, "worker");
w.print();
t.print();
s.print();
Worker w1(1006, "worker");
s.print();
cout << sizeof(Worker) << endl;//为8字节,静态数据成员不占类的内存单元
}
运行结果: