类的继承
● 通过类的继承(派生)来引入“是一个”的关系( 17.2 — Basic inheritance in C++)
– 通常采用 public 继承( struct V.S. class )
– 注意:继承部分不是类的声明
– 使用基类的指针或引用可以指向派生类对象
struct Base
{
};
struct Base2 : Base
{
};
struct Derive : Base2 //注意,不是声明,该语句等价于struct Derive : public Base,即struct缺省继承方式为public
//class Derive : Base2 //等价于class Derive : private Base,即class缺省继承方式为private
{
};
int main()
{
Derive d;
Base& ref = d; //OK
Base* ptr = &d; //OK
}
– 静态类型 V.S. 动态类型
struct Base
{
void funBase() {} //静态类型
};
struct Base2 : Base
{
void funBase2() {} //静态类型
};
struct Derive : Base2
{
void funDerive() {} //静态类型
};
struct Derive2 : Base2
{
void funDerive2() {} //静态类型
};
int main()
{
Derive d;
Derive2 d2;
Base& ref = d; //静态类型: 即编译期就能决定的类型且不能改变
Base* ptr = &d; //动态类型
ref.funBase(); //OK,静态类型没有改变
ref.funDerive(); //静态类型不能发生改变,Error: No member named 'funDerive' in 'Base'
ptr = &d2; //OK,动态类型可以在运行期发生改变
return 0;
}
– protected 限定符:派生类可访问
struct Base
{
private:
void funBase() {}
};
struct Derive : Base
{
void funDerive()
{
funBase(); //Error: 'funBase' is a private member of 'Base'
}
};
int main()
{
Base b;
b.funBase(); //Error: 'funBase' is a private member of 'Base'
return 0;
}
struct Base
{
void funBase() {}
};
struct Derive : Base
{
void funDerive()
{
funBase(); //OK
}
};
int main()
{
Base b;
b.funBase(); //OK
Derive d;
d.funBase(); //OK
d.funDerive(); //OK
return 0;
}
struct Base
{
protected:
void funBase() {}
};
struct Derive : Base
{
void funDerive()
{
funBase(); //OK
}
};
int main()
{
Base b;
b.funBase(); //Error: 'funBase' is a protected member of 'Base'
Derive d;
d.funBase(); //Error: 'funBase' is a protected member of 'Base'
d.funDerive(); //OK
return 0;
}
● 类的派生会形成嵌套域
– 派生类所在域位于基类内部
– 派生类中的名称定义会覆盖基类
struct Base
{
int val = 2;
};
struct Derive : Base
{
void funDerive()
{
std::cout << val << std::endl;
}
int val = 3;
};
int main()
{
Derive d;
d.funDerive();
return 0;
}
struct Base
{
int val = 2;
};
struct Derive : Base
{
void funDerive()
{
std::cout << val << std::endl;
}
//int val = 3;
};
int main()
{
Derive d;
d.funDerive();
return 0;
}
– 使用域操作符显式访问基类成员
struct Base
{
int val = 2;
};
struct Derive : Base
{
void funDerive()
{
std::cout << val << std::endl;
std::cout << Base::val << std::endl;
}
int val = 3;
};
int main()
{
Derive d;
d.funDerive();
return 0;
}
– 在派生类中调用基类的构造函数
struct Base
{
Base()
{
std::cout << "Base()\n";
}
};
struct Derive : Base
{
Derive()
{
std::cout << "Derive()\n";
}
};
int main()
{
Derive d;
return 0;
}
struct Base
{
Base(int)
{
std::cout << "Base()\n";
}
};
struct Derive : Base
{
Derive(int a) //缺省构造函数调用基类的缺省构造函数,Error: Constructor for 'Derive' must explicitly initialize the base class 'Base' which does not have a default constructor
{
std::cout << "Derive()\n";
}
};
int main()
{
Derive d;
return 0;
}
struct Base
{
Base(int)
{
std::cout << "Base()\n";
}
};
struct Derive : Base
{
Derive(int a) //缺省构造函数调用基类的缺省构造函数,Error: Constructor for 'Derive' must explicitly initialize the base class 'Base' which does not have a default constructor
: Base(a) //显式调用基类的构造函数
{
//Base::Base(a); //Error: Qualified reference to 'Base' is a constructor name rather than a type in this context
std::cout << "Derive()\n";
}
};
int main()
{
Derive d(2);
return 0;
}
参考
深蓝学院: C++基础与深度解析
17.2 — Basic inheritance in C++