简体   繁体   English

C ++:设计建议

[英]C++: design advice

I need some advice on the design of my class hierarchy. 我需要一些有关类层次结构设计的建议。 The 'skeleton' of my current design is 我当前设计的“骨架”是

template <class X>
class BASE {
  public:
    virtual void f() {
        x_.f2(m_);
    }

    void g() {
        /* do stuff here*/
        x_.g();
    }

    /* more member functions here*/

  protected:
    X x_;
    int m_;
};

template <class X>
class DERIVED : BASE<X> {
    public:
      virtual f() override {
         x_.f1();
      }

     protected:
     using BASE<X>::x_;
     using BASE<X>::m_;
};

and finally I have two more classes like this 最后我又有两个这样的课程

struct X1 {
  void f1();
  void g();
};

struct X2 : X1 {
void f2(int m);
};

I would like to be able to create an instance of DERIVED<X1> . 我希望能够创建DERIVED<X1>的实例。 To do that, the compiler will create first an instance of BASE<X1> , in which case it will complain that X1 does not have a member function f2 (even though in practice it would never be called since the calling function f() is virtual). 为此,编译器将首先创建BASE<X1>的实例,在这种情况下,它将抱怨X1没有成员函数f2(尽管实际上它永远不会被调用,因为调用函数f()是虚拟)。

I understand that this is a bad design since in order to have a templated class, the template arguments must have the same interface. 我知道这是一个糟糕的设计,因为要拥有模板化的类,模板参数必须具有相同的接口。 In my case X1 and X2 have a common interface but X2 has more functionality, which creates the above problem. 在我的情况下,X1和X2具有公共接口,但是X2具有更多功能,从而产生了上述问题。 I understand I could create an f2 function in X1 which does nothing, but ideally I would like to avoid that. 我知道我可以在X1中创建一个不执行任何操作的f2函数,但理想情况下,我希望避免这种情况。

I would welcome any suggestions for improving the design. 我欢迎任何改进设计的建议。 Thanks in advance! 提前致谢!

First advice is not to use protected atributes. 首要建议是不要使用受保护的属性。 Is is breaking incapsulation. 正在打破封装。

The second advice is to make virtual void f()=0 pure virtual without implementation. 第二种建议是使virtual void f()=0完全不执行而成为纯虚virtual void f()=0 In such there will be no error in the derived class. 这样,派生类就不会有错误。

Avoid deriving from a concrete class. 避免派生出具体的类。 Lift interfaces/ABCs to the top, make all concrete classes leaves. 将接口/ ABC提升到顶部,使所有具体类都离开。 It's a general advice for many kinds of design difficulties. 这是针对许多设计难题的一般建议。

In your particular case, instead of this: 在您的特定情况下,请执行以下操作:

             BASE    // concrete
              | 
           DERIVED

use this: 用这个:

             BASE   // fully abstract
            /   \
BASIC_DERIVED    ADVANCED_DERIVED

Now f is pure virtual in BASE and all is well. 现在fBASE是纯虚拟的,一切都很好。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM