一个类设计上的问题!高分送高手!
有下面2个类:
class A
{
public:
Init();//实现与B不同
Do();//实现与B不同
Rel();//实现与B相同
private:
data1;//B也有
data2;//B也有
data3;//B没有
}
class B
{
public:
Init();//实现与A不同
Do();//实现与A不同
Rel();//实现与A相同
private:
data1;//A也有
data2;//A也有
data4;//A没有
}
类A和类B的成员函数的语义一样,但是函数体不同, 他们的数据成员大部分相同,也有不同的。
现在要给这两个类设计一个基类。限制是基类的成员变量必须是private!请问基类该怎么设计?请考虑下面的方案那种比较好:
1:基类作为纯接口,只提供Init(),Do(),Rel()几个纯虚函数,没有数据成员。但是这样的话,Rel()这种函数2个子类都是一样的,却要分别实现,还有相同的数据也要在每个子类分别声明,总觉得有点冗余!
2:由于A,B的rel相同,把Rel的实现提到基类,Rel()所操作的成员也提到基类. 但这样的话,基类的成员变量必须是private! 所以,只好提供Set(),Get()函数,但是在子类的Init()和Do()中会大量引用基类的成员,所以每次要引用基类的成员都要去Get, Set.而且,Init和Rel是配对函数,却分别放到了子类和基类.也感觉不好!
请问大家有什么更好的办法的? 谢谢!
注:不能破坏强制条件:基类的成员变量必须是private!
[解决办法]
(1) 既然 data1 和 data2 是共有的, 那么基类就不应作为纯接口, 而应该让 data1 和 data2 在基类中。
(2) 既然你想要把数据私有起来, 那么就必须得用 get() 和 set(), 没有别的选择。
(3) 基类中也实现 init(), 然后在两个子类中的init() 方法中, 可以对 父类的 init() 进行调用, 并增加自己的独特部分的功能
[解决办法]
Set(),Get() 没有什么不好
[解决办法]
class Father{
virtual void Init()=0;
virtual void Do() = 0;
virtual void Rel() = 0;
}
另外对上面Init的函数表示一下我的看法,从名字看出来这是一个初始化对象的操作,这里为什么不用构造函数呢?
既:
Father();
或许LZ没有理解面向对象?
另外 既然必须私有,用Get和Set应该是一种很好的操作,没有什么不好@
[解决办法]
类的合理更重要吧,
data1;
data2; 两个类都有,哪就在基类中定义。你已经限制只能为private
哪只能用get,set函数进行读写。
Rel()的实现相同,如果Rel的操作没涉及子类自己的成员或函数,也应该放入到基类中。
Init();
Do();
子类各有不同实现,就在基类中声明为虚函数处理。
[解决办法]
up up 对于这点:
(3) 基类中也实现 init(), 然后在两个子类中的init() 方法中, 可以对 父类的 init() 进行调用, 并增加自己的独特部分的功能
要注意父类和子类函数间的隐藏规则.要是我,对基类的方法定义成虚函数,用Set(),Get() 来实现基类私有成员的操作.
[解决办法]
init和do作成虚函数,rel为非虚的。
提供get和set函数。
[解决办法]
既然讨论设计,你为什么要给自己加这个“限制是基类的成员变量必须是private”无谓的限制呢。
第二:你为什么要基类 呢?是多态的需要?是代码去重复的需要?
[解决办法]
支持
你反问这2个问题,你的面试一定高分。
其实这种题目没有答案
只是设计的思维问题
我猜测就连你们的答辩管也希望你有自己的想法
[解决办法]
class base
{
public:
virtual Init()=0;
virtual Do()=0;
virtual Rel();
virtual set();
virtual get();
private:
data1;
data2;
}
[解决办法]
非常同意 huzhangyou(信仰(http://www.libing.net.cn)) 的观点。
面试官也许知识想了解你分析问题的能力和思维的逻辑性。
就问题本身而言,用Set Get就好了,编辑器优化为内联,也没有什么性能损失,没什么不好的。
但非要扣字眼,不用private,那就用友元吧,可以满足题目的要求。
[解决办法]
class base
{
public:
virtual Init()=0;
virtual Do()=0;
Rel();
virtual set();
virtual get();
private:
data1;
data2;
}
这样吧,不过还少返回类型