自动强制转换

时间:2020-03-06 14:39:08  来源:igfitidea点击:

在弄乱了我以前的帖子的描述之后,我坐了下来,试图传达我的确切意图。

我有一个叫做P的类,它执行一些不同的目的。我也有PW,它在P上执行一些独特的目的。PW没有成员变量,只有成员函数。

根据此描述,我们将假定代码将如下所示:

class P
{
public:
    void a( );
};

class PW
{
public:
    PW( const P& p ) : p( p ) { }
    void b( );
    P& p;
};

class C
{
public:
    P GetP( ) const { return p; }   
private:
    P p;
};

// ...
    PW& p = c.GetP( ); // valid
// ...

但是,这带来了一个问题。我不能在没有无处不在的情况下调用P的功能。

// ...
    p->p->a( )
// ...

我想做的就是调用p-> a()并让它自动确定我要调用P的成员函数。

另外,拥有PW的成员a并不能真正扩展如果我向P添加(或者删除)另一个函数,则需要向PW添加(或者删除)该函数。

解决方案

如果像前面的问题中那样使P成为PW的超类,则可以调用p-> a()并将其定向到P类。看来我们已经考虑并拒绝了问题。如果是这样,我们是否愿意详细说明为什么这对我们不起作用?

我们可以尝试覆盖operator *和operator->以返回对嵌入式p的访问。
这样的事情可能会解决问题:

class P
{
  public:
    void a( ) { std::cout << "a" << std::endl; }
};

class PW
{
  public:
    PW(P& p) : p(p) { }

    void b( ) { std::cout << "b" << std::endl; }

    P & operator*()  { return p;  }
    P * operator->() { return &p; }

  private:
    P & p;
};

class C
{
  public:
    P & getP() { return p; }

  private:
    P p;
};

int main()
{
  C c;
  PW pw(c.getP());

  (*pw).a();
  pw->a();
  pw.b();

  return EXIT_SUCCESS;
}

此代码打印

a
a
b

但是,由于operator *和operator->的语义有些混乱,因此此方法可能会使用户感到困惑。

我认为我们需要考虑一下PW和P之间存在什么样的关系。

这是一种关系吗?是PW的PW实例吗?那么让PW从P继承将是有意义的。

有关系吗?然后,我们应该坚持遏制,忍受句法上的不便。

顺便说一句,在类的公共接口中公开对成员变量的非常量引用通常不是一个好主意。