class Employee
{
public:
Employee(const std::string& name, const std::string& ssn);
const std::string& get_name() const;
void print(std::ostream& out) const;
void print(std::ostream& out, const std::string& msg) const;
//让成员变量为protected,好处是子类可以直接调用m_name,m_ssn.
// 坏处是不知道子类会拿m_name和m_ssn做什么.
//建议成员变量用private.
protected:
std::string m_name;
std::string m_ssn;
};
//构造函数
Employee::Employee(const string& name, const string& ssn):m_name(name),m_ssn(ssn)
{
//initializer list sets up the values.
}
inline const std::string& Employee::get_name() const
{
return m_name;
}
inline void Employee::print(std::ostream& out) const
{
out << m_name << endl;
out << m_ssn << endl;
}
inline void Employee::print(std::ostream& out, const std::string& msg) const //两个print函数名相同,参数不同,函数重载
{
out << msg << endl;
print(out); // 编译器会根据参数的数量类型不同,决定该调用哪一个函数.
//调用了第一个print函数,而不是抄写一遍. 尽量利用之前写的代码. 避免代码复制.
}
class Manager:public Employee
{
public:
Manager(const std::string& name, const std::string& ssn, const std::string& title);
const std::string title_name() const;
const std::string& get_title() const;
void print(std::ostream& out) const;
private:
std::string m_title;
};
//初始化列表
Manager::Manager(const string& name, const string& ssn, const string& title=""):Employee(name,ssn),m_title(title)
{
}
inline void Manager::print(std::ostream& out)
{
Employee::print(out); //尽量避免代码重写 函数重构时写解析符.
out << m_title << endl;
}
inline const std::string& Manager::get_title() const
{
return m_title;
}
inline const std::string Manager::title_name() const
{
return string(m_title + ": " + m_name);
}
int main()
{
Employee bob("Bob Jones", "555-44-0000");
//父类Employee,此时Employee中的bob对象的protected成员变量m_name = "Bob Jones", m_ssn = "555-44-0000" (成员变量是对象的,成员函数是类的)
Manager bill("Bill Smith", "666-55-1234", "Important Person");
//子类Manager的对象bill中的私有成员变量m_title = "Important Person", 同时m_name = "Bill Smith", m_ssn = "555-44-0000".
string name = bill.get_name();
//子类调用父类的成员函数,name = "Bill Smith".
//string title = bob.get_title(); //此行出错,不能如此调用,父类不能调用子类的东西.
cout << bill.title_name() << '\n' << endl;
// "Important Person : Bill Smith
bill.print(cout); //"Bob Jones" "555-44-0000"
//"Important Person.
bob.print(cout); //"Bob Jones" "555-44-0000"
bob.print(cout, "Employee:"); //Employee: "Bob Jones" "555-44-0000"
//bill.print(cout, "Employee:"); //此行出错
return 0;
}
#include <iostream>
using namespace std;
class A
{
public:
A(int ii):i(ii)
{
cout << "A::A()" << endl;
}
`A()
{
cout << "A::`A()" << endl;
}
void print()
{
cout << "A::f()" << endl;
}
void set(int ii)
{
i = ii;
}
private:
int i;
};
class B:public A
{
public:
B():A(15) {} //B的构造函数
void f()
{
set(20);
print();
}
};
int main()
{
B b; //程序报错,原因B b,需要调用父类A的无参数构造函数. A类中没有.
//初始化子类,而父类是子类的一部分,则父类也需要初始化. 子类不懂父类是初始化的,所以需要交给父类自己初始化. 而此时A没有给出缺省构造函数,所以需要告诉如何调用A的构造函数.
//解决方法:添加B的构造函数 B():A(15) 则首先对A(15)初始化,然后调用A的构造函数,然后调用B的构造函数 (初始化列表)
b.set(10);
b.print();
b.f();
return 0;
}
初始化列表的顺序
c++
class father
{
public:
father(int x, float y) { }
private:
int x;
float y;
};
class son: public father
{
public:
son:father(10, 10.0, 5);//按照声明的顺序, 父类最先,子类列表的顺序初始化. x=10, y = 10.0, m = 5.
private:
int m;
};
//析构的时候,先把子类清理,再清理父类的.
注意:如果没有经过初始化列表的方式,传送参数给父类的话,将会调用父类的无参数构造函数.
只要C++这么做的:
当父类中有成员函数print(), print(int i)
子类中也有成员函数print()
此时子类B b, b.print() 此时父类的成员函数print()和print(int i)都隐藏了.