c++程序设计(下)—— 兼谈对象模型
1.导读
学习目标
-
在先前基础课程所培养的正规、大器的编程素养上,继续探讨更多技巧。
-
泛型编程(Generic Programming)和面向对象编程(Object-Oriented Programming)虽然分属不同思维,但它们是c++的技术主线,所以本可能也讨论template(模板)。.
-
深入探索面向对象之继承关系(Inheritance)所形成的对象模型(Object Model),包括隐藏于底层的
this
指针,vptr
(虚指针),vtbl
(虚表),virtual mechanism(虚机制),以及virtual function(虚函数)造成的polymorphism(多态)效果。
2.conversion function(转换函数)
把这种类对象转化为另一种类对象。
-
转换函数没有返回值(编译器给出,防止错误)
-
转换函数通常需要加const,因为不会改变类中数据
class Fraction
{
public:
Fraction(int num,int den = 1)
: m_numerator(num),m_denominator(den){
}
//将该类与operator后所跟类型相互转化时,调用下方函数
operator double() const{
return (double)m_numerator/(double)m_denominator;
}
private:
int m_numerator; //分子
int m_denominator; //分母
}
//使用场景
{
Fration f(3,5);
double d = 4+f; //因为没有对int+Fration的重载,故调用operator double()将f转为0.6
}
3.non-explicit-one-argument ctor(没有explicit关键字的一实参构造函数)
把另一种类对象,转化为该种类对象。
class Fraction
{
public:
Fraction(int num,int den = 1) //non-explicit-one-argument ctor
: m_numerator(num),m_denominator(den){
}
Fraction operator + (const Fraction& f){
return Fraction(...);
}
private:
int m_numerator;
int m_denominator;
}
//使用场景
{
Fration f(3,5);
Fraction d2 = f+4; //对Fraction+Fraction的情形进行过重载,又因为Fraction的构造函数只需要传入一个参数即可。故4转化为Fraction(4,1),再调用operator+
}
conversion function vs.non-explicit-one-argument ctor
class Fraction
{
public:
Fraction(int num,int den = 1) //non-explicit-one-argument ctor
: m_numerator(num),m_denominator(den){
}
//conversion function
operator double() const{
return (double)m_numerator/(double)m_denominator;
}
//non-explicit-one-argument ctor 配套+号的重载
Fraction operator + (const Fraction& f){
return Fraction(...);
}
private:
int m_numerator;
int m_denominator;
}
//使用场景
{
Fration f(3,5);
Fraction d2 = f+4; //[Error] ambiguous 两种方式均可,意义不明
}
explicit-one-argument ctor
为了解决上文提到的错误形式,我们需要在构造函数前加上explicit
关键字,明确构造函数定义,使得对象只能以复合构造函数定义的形式创建,不可从其他类对象转化而来。
class Fraction
{
public:
explicit Fraction(int num,int den = 1) //non-explicit-one-argument ctor
: m_numerator(num),m_denominator(den){
}
//conversion function
operator double() const{
return (double)m_numerator/(double)m_denominator;
}
//non-explicit-one-argument ctor 配套+号的重载
Fraction operator +