继承之下的赋值运算符重载
1.引出“隐藏”
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;
};
int main()
{
A a;
B b;
a.print();
b.set();
b.print();
cout << sizeof(B) << endl;
return 0;
}
在A,B两类里,都有同名的成员函数和数据成员,所以将派生下来的A的print隐藏了。
隐藏:派生类的成员函数和基类的函数同名同参,则将基类的函数隐藏
如果需要对象b调用A类的成员函数,可以这样:b.A::print();
2.继承类的赋值问题
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是指针,所以必须先释放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) { cout << "有参构造函数" << endl; }
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;
};
Student s;
这里为什么会先调用Person类的构造函数呢?
这是因为当创建Student类对象s时并未传参,所以首先调用Person(基类)的无参构造函数,再调用Student(子类)的无参构造函数。
——————————————————————————————————
Student s1(1001, "zhangsan", 'f', 20, 78);
跟上面一样,首先调用Person(基类)的有参构造函数,再调用Student(子类)的有参构造函数。
————————————————————————————————————
Student s2(s1);
必须调用Student类的拷贝构造函数。
系统默认的拷贝构造函数实现的只能是浅拷贝,即直接将原对象的数据成员值依次复制给新对象中对应的数据成员,并没有为新对象另外分配内存资源
在重新定义拷贝构造函数后,默认拷贝构造函数与默认构造函数就不存在了;
重新定义构造函数后,默认构造函数不存在了,但是默认拷贝构造函数还存在;
—————————————————————————————————————————————
s = s1;
s.print();
需要对“=”的重载构造函数,必须是引用赋值。