急 请教基类不应该有 protected成员 吗
急! 请问基类不应该有 protected成员 吗?
我们公司一个牛人说的:“一个好的设计,不应该让基类有protected成员。”
请问他说的话对吗?如果是对的,请给出理由。如果不对,也请说明理由。
谢谢!
------解决方案--------------------
如果基类不应该有protected成员,那么C++就可以废除protected关键字了。
------解决方案--------------------
这个也不应该这么武断啊。C++中使用这个也是有道理的。要没有用,JAVA和C#中为什么还要提供这个关键字啊。
------解决方案--------------------
在具体的设计中再做决定吧,其他人说的只是他们遇到的设计中的一些经验罢了。
------解决方案--------------------
好像不太对,protected 关键字的用意是在于对外屏蔽,对子类公开的,要不然“继承”二字怎么讲 ,它只继承了成员函数,而成员函数可是要对成员变量进行操作的啊...
------解决方案--------------------
protected变量确实没有价值。
------解决方案--------------------
呵呵,我在某些地方也看到过这个样的说法.
基本的意思应该是让基类的变量对派生类 "公开 "和向外界 "公开 "其实本质是一样的,这样做的后果都是对变量很难做到有效的控制.同时它们又推荐这样的做法:
1. 将基类的所有变量声明成private的;
2. 对于需要向派生类公开的变量,可以提供protected类型的访问函数(get/set)来控制基类的变量.
这样做的好处在于避免直接操作基类变量,而是通过有效的接口来完成.
------解决方案--------------------
我遇到的一个牛人,他从来不在基类定义protected的变量,如果子类的确需要,他也定义为private型的变量,不过他是提供protected的成员函数
我觉得你们的那个牛人说得不对,之所以要定义在基类里面,是很多子类需要使用(在多个子类里面都定义的话,麻烦),要是只有一个子类,那最好把需要在基类定义为protected的变量在子类定义为private型
------解决方案--------------------
没错,凡事都没有绝对
------解决方案--------------------
taodm我觉得你说得应该没错。
但问题是那种仅限于模块内部实现的简单性和不严格性没有太多必要拿到台面上讨论。:P
------解决方案--------------------
基类的protected主要是为了解决代码复用的问题。试想,如果protected的方法应该是实现,完全可以不暴露给派生类。如果是接口,要么它应该可以public,要么违背了单一职责原则:对外一套interface和对派生类的interface完全不能相容却揉到了一起。不过,违背单一职责也没什么可怕,就看代码复用的好处够不够大,牺牲的弹性是不是能承受。所以,拥有protected成员的类肯定难以当作接口来看待,一般来说,只能当作是杂合类。
然而,如果base压根就不打算作为接口,那么使用protected就没什么不合适的,此时protected只是适当地使用语言的功能来提高一些安全性。典型的,GP中的一些垫片类。这些类只是满足程序结构性上的一些要求:
template <Base> class Implement{
Call Base::methodA();
};
但是,在GP时,这个Base有concept等价与methodA的,但名字不叫methodA,很容易想到加一个垫片:
template <Base> class Foo{
protected: methodA() { call Base::methodB();}
};
在Implement <Foo <Base> > 类型中,Foo中的protected没什么问题,因为Foo的虽然是基类,但他只是要完成程序结构性的东西,加上protected只是加强一点安全性。当然,个人认为,此处用public也没什么大问题。
------解决方案--------------------
是啊,我 宁愿T & Get(){return t;}也还从没有pubic一个成员,但我不否认它们(目前)其实是相同的。
------解决方案--------------------
但是,一个
public / protected:
T& Get () const { return t_; }
private:
void Set (const T& t); // private, unimplemented
T t_;
和
public / protected:
T t_;
是完全不等价的
我们公司一个牛人说的:“一个好的设计,不应该让基类有protected成员。”
请问他说的话对吗?如果是对的,请给出理由。如果不对,也请说明理由。
谢谢!
------解决方案--------------------
如果基类不应该有protected成员,那么C++就可以废除protected关键字了。
------解决方案--------------------
这个也不应该这么武断啊。C++中使用这个也是有道理的。要没有用,JAVA和C#中为什么还要提供这个关键字啊。
------解决方案--------------------
在具体的设计中再做决定吧,其他人说的只是他们遇到的设计中的一些经验罢了。
------解决方案--------------------
好像不太对,protected 关键字的用意是在于对外屏蔽,对子类公开的,要不然“继承”二字怎么讲 ,它只继承了成员函数,而成员函数可是要对成员变量进行操作的啊...
------解决方案--------------------
protected变量确实没有价值。
------解决方案--------------------
呵呵,我在某些地方也看到过这个样的说法.
基本的意思应该是让基类的变量对派生类 "公开 "和向外界 "公开 "其实本质是一样的,这样做的后果都是对变量很难做到有效的控制.同时它们又推荐这样的做法:
1. 将基类的所有变量声明成private的;
2. 对于需要向派生类公开的变量,可以提供protected类型的访问函数(get/set)来控制基类的变量.
这样做的好处在于避免直接操作基类变量,而是通过有效的接口来完成.
------解决方案--------------------
我遇到的一个牛人,他从来不在基类定义protected的变量,如果子类的确需要,他也定义为private型的变量,不过他是提供protected的成员函数
我觉得你们的那个牛人说得不对,之所以要定义在基类里面,是很多子类需要使用(在多个子类里面都定义的话,麻烦),要是只有一个子类,那最好把需要在基类定义为protected的变量在子类定义为private型
------解决方案--------------------
没错,凡事都没有绝对
------解决方案--------------------
taodm我觉得你说得应该没错。
但问题是那种仅限于模块内部实现的简单性和不严格性没有太多必要拿到台面上讨论。:P
------解决方案--------------------
基类的protected主要是为了解决代码复用的问题。试想,如果protected的方法应该是实现,完全可以不暴露给派生类。如果是接口,要么它应该可以public,要么违背了单一职责原则:对外一套interface和对派生类的interface完全不能相容却揉到了一起。不过,违背单一职责也没什么可怕,就看代码复用的好处够不够大,牺牲的弹性是不是能承受。所以,拥有protected成员的类肯定难以当作接口来看待,一般来说,只能当作是杂合类。
然而,如果base压根就不打算作为接口,那么使用protected就没什么不合适的,此时protected只是适当地使用语言的功能来提高一些安全性。典型的,GP中的一些垫片类。这些类只是满足程序结构性上的一些要求:
template <Base> class Implement{
Call Base::methodA();
};
但是,在GP时,这个Base有concept等价与methodA的,但名字不叫methodA,很容易想到加一个垫片:
template <Base> class Foo{
protected: methodA() { call Base::methodB();}
};
在Implement <Foo <Base> > 类型中,Foo中的protected没什么问题,因为Foo的虽然是基类,但他只是要完成程序结构性的东西,加上protected只是加强一点安全性。当然,个人认为,此处用public也没什么大问题。
------解决方案--------------------
是啊,我 宁愿T & Get(){return t;}也还从没有pubic一个成员,但我不否认它们(目前)其实是相同的。
------解决方案--------------------
但是,一个
public / protected:
T& Get () const { return t_; }
private:
void Set (const T& t); // private, unimplemented
T t_;
和
public / protected:
T t_;
是完全不等价的