【问题标题】:Is it considered good practice to change the protection level of a method?更改方法的保护级别是否被认为是良好做法?
【发布时间】:2011-09-28 19:26:36
【问题描述】:

换句话说,如果我有课

class A
{
public:
   A() { .. }
   virtual void somemethod() { .. }
};

可以写吗

class B : public A
{
public:
   B() { .. }
protected:
   virtual void somemethod() { .. }
};

或者这种方法有一些缺点吗?

【问题讨论】:

    标签: c++ polymorphism access-specifier


    【解决方案1】:

    这种方法的主要缺点是人们总是可以获取指向A 的指针/引用并调用somemethod 哪里是公共的。你为什么想做这样的事情?如果BA,并且As 有一个public somemethod,那么Bs 也是如此。

    【讨论】:

    • 因为如果你有一个类,你可能想要限制某些方法的可访问性。例如如果你在基类中有方法 A(int),A(char),A(double) 也许你想在派生类中限制 A 的使用说只允许 A(char)
    • 另一种方法是在错误的上下文中使用时抛出异常,但我认为最好完全限制该方法的使用。
    • @Anders K.:重新设计类可能会更好。在这种情况下,继承不应该是私有的吗?
    • @AndersK。 ...但您不会限制在派生类中的使用,仅在用作派生类时使用。也就是说,正如 K-ballo 指出的那样,用户可以向上转换并调用基类上的方法,它是公共的。也就是说,您所做的是提供无法解决您的实际问题的复杂部分解决方案。
    • 而您的实际问题是,“如果有人试图在通用代码中用类型 B 代替 A,我想违反 LSP(的变体)。请帮助我”。经验丰富的程序员对此的普遍反应是“不!”。
    【解决方案2】:

    我会说这违背了多态的目的,因为当你编写一个接受多态类型的函数时,派生类型应该同样适用于它:

    void fun(A* a){
       a->somemethod();
    }
    ...
    A* a = new B();
    fun(a); // Shouldn't this work?!
            // According to Liskov Principle, you are doing it wrong!
            // but really who cares, it depends on your justification
            // of a solution to the the problem at hand.
    

    恕我直言,这取决于您要解决的具体问题,因为我不相信“总是”成功的“最佳实践”。

    【讨论】:

    • 好吧,从语言/编译器的角度来看,它是有效的,但你为什么要首先定义一个虚函数。
    【解决方案3】:

    这种方法没有缺点。唯一的限制是不能用B object/pointer/reference 调用B::somemethod()。现在只能使用A 的指针或引用来调用它。

    事实上,我已经看到,有时这种限制是有意引入的。这样的场景是class B 的开发者想要传达这样的信息:somemethod() 应该仅以多态方式使用基类句柄来调用。

    【讨论】:

      【解决方案4】:

      没有缺点。

      但这样做并没有真正的优势。
      您仍然可以通过指向案例类的指针访问somemethod()

      所以在技术方面没有缺点也没有优点。
      所以现在我们开始讨论使用你的对象是多么容易。这里有一个缺点,因为您混淆了对象的用户(为什么它在这个级别受到保护而不是较低级别)?因此,您正在为自己创造工作,记录您做出此决定的原因以及您试图通过使用此技术实现的目标。

      您真正想要实现的目标是什么?

      【讨论】:

      • 等等,所以有缺点但没有缺点?有什么区别?
      • 没有Technical 缺点。不利的一面是用户的心理。
      猜你喜欢
      • 2021-11-13
      • 2011-05-26
      • 1970-01-01
      • 1970-01-01
      • 2018-04-08
      • 2012-09-07
      • 1970-01-01
      • 2018-08-11
      • 2015-07-24
      相关资源
      最近更新 更多