您的位置:首页 > 其它

面向对象——类设计(一)

2015-11-20 15:14 323 查看
如果一个类将自己的成员变量声明为
protected
,则该类很有可能作为多态基类

一个类的成员变量一般不声明为
public
(如果非声明为public不可的话,使用struct岂不是更好),而
protected
private
的区别正在于所修饰的变量是否子类可见。

一个类的析构函数如果为virtual的话,则该类很多可能作为多态基类,则该类应有另外的virtual成员函数

实现一个类的顺序

所有封装的成员变量

围绕成员变量的构造函数

成员变量的存取

其他成员变量

私有成员函数

有些类内部会有一些私有的函数,除了友元之外,

这些私有的函数只开放给类自身,也即仅会被类内部其他成员函数所调用,属于劳模,属于干脏活累活的人,属于幕后的工作人员,也即幕后英雄;

所以结论是什么,私有成员函数仅被类内其他成员函数所调用,设计与实现的顺序是,先设计私有,后设计公有。是先设计与实现私有成员函数,再实现需要依赖该私有成员函数的共有成员函数;

构成重载 vs 不构成重载?

DAttrInfo& cast_to_d();
const DAttrInfo& cast_to_d() const;

DAttrInfo& cast_to_d();
DAttrInfo& cast_to_d() const;
// 以上均可构成重载
DAttrInfo& cast_to_d();
const DAttrInfo& cast_to_d();
// 无法重载仅按返回类型区分的函数


默认构造和默认析构

类的默认构造函数会调用其全部成员变量(不包括内置类型)的默认构造函数(如果存在的话),同理类的默认析构函数会调用其全部成员变量的默认析构函数(如果存在的话)。

class Widget
{
public:
Widget() { cout << "Widget::Widget()" << endl;}
~Widget() { cout << "Widget::~Widget()" << endl;}
};

class Test
{
private:
int x;
Widget w;
public:
int get() const { return x;}
};

int main(int, char**)
{
Test t;
cout << t.get() << endl;
return 0;
}


为多态基类声明virtual析构函数

enum TimerType
{
Atomic,
Water,
Writst
};
class TimeKeeper
{
public:
/*virtual*/ ~TimeKeeper() { cout << "TimeKeeper::~TimeKeeper()" << endl;}
};

class AtomicClock :public TimeKeeper
{
public:
~AtomicClock() { cout << "AtomicClock::~AtomicClock()" << endl;}
};

TimeKeeper* getTimeKeeper(TimeKeeperType type)
{
TimeKeeper* tk;
switch(type)
{
case Atomic:
tk = new AtomicClock;
break;

case Water:
tk = new WaterClock;
break;

case Wrist:
tk = new WristWatch;
break;

default:
tk = nullptr;
break;
}
return tk;
}

int main(int, char**)
{
TimeKeeper* tk = getTimeKeeper(Atomic);
delete tk;
// TimerKeeper::TimerKeeper()
// 如果析构函数不是virtual的,可见不会调用子类的析构函数
// 如果将基类的析构函数声明为virtual,
// 当derived class对象经由base class指针删除时,就会先调用基类的析构函数,再调用父类的析构函数
return 0;
}


再次请深入理解,virtual函数(普通函数以及析构函数)的目的是允许derived class的实现得以客制化
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: