交叉分配操作员?

时间:2009-03-18 17:11:50

标签: c++

现在是我第一个问题的时候了。你如何在两个类之间交叉赋值运算符?

class B;

class A {
public:
A &operator = ( const B &b );
friend B &B::operator = ( const A &a ); //compiler error
};

class B {
public:
B &operator = ( const A &a );
friend A &A::operator = ( const B &b );
};

我搜索了如何转发声明成员函数,如:

class B;
B &B::operator = ( const A &a ); //error

但我没有找到任何东西。而且我不想让全班的朋友互相帮助。我该怎么做?

4 个答案:

答案 0 :(得分:2)

无法转发声明成员函数。我不确定是否有比这更优雅的方式来获得你想要的东西(我从来没有理由做这样的事情),但是可以做的是让第二类成为非成员函数这是两个类的朋友,并委托复制到它。请注意,operator =本身不能是非成员,但是这样的事情应该有效:

class B;

class A {
public:
  A& operator = ( const B &b );
  friend B& do_operator_equals ( B& b, const A& b);
};

class B {
public:
  B &operator = ( const A &a );
  friend A& A::operator = ( const B &b );
  friend B& do_operator_equals ( B& b, const A& a);
};

然后在您的实施文件中

A& A::operator= (const B& b) {
   // the actual code to copy a B into an A
   return *this;
}

B& B::operator= (const A& a) {
   return do_operator_equals(*this, a);
}

B& do_operator_equals(B& b, const A& a) {
  // the actual code to copy an A into a B
  return b;
}

编辑:让A和B倒退,哎呀。固定的。

答案 1 :(得分:1)

编译器错误的原因是循环依赖。每个operator =()函数都需要知道另一个类中的operator =()函数,因此无论您在哪个类中定义类,都会出现错误。

这是一种解决方法。它不是很优雅,但它会做你想要的:

class A;
class B;

A & set_equal(A & a, const B & b);
B & set_equal(B & a, const A & a);

class A
{
    private:
        int x;
    public:
        A & operator=(const B & b) { return set_equal(*this, b); }
        friend B & set_equal(B & b, const A & a);
        friend A & set_equal(A & a, const B & b);
};

class B
{
    private:
        int y;
    public:
        B & operator=(const A & a) { return set_equal(*this, a); }
        friend A & set_equal(A & a, const B & b);
        friend B & set_equal(B & b, const A & a);
};

A & set_equal(A & a, const B & b) { a.x = b.y; return a; }
B & set_equal(B & b, const A & a) { b.y = a.x; return b; }

您也可以通过继承来解决这个问题。

编辑:这是一个使用继承的示例。如果复制过程只需要访问A和B共享的一些公共数据,这将起作用,如果=运算符具有任何意义,这似乎很可能。

class A;
class B;

class common
{
    protected:
        int x;
        void copyFrom(const common & c) { x = c.x; }
};

class A : public common
{
    public:
        A & operator=(const common & c) { copyFrom(c); return *this; }
};

class B : public common
{
    public:
        B & operator=(const common & c) { copyFrom(c); return *this; }
};

答案 2 :(得分:0)

为什么你希望他们成为朋友? 这似乎是不可能的你写它的方式。解决方案可能是根本不让他们成为朋友。

答案 3 :(得分:-3)

你没有转发声明成员函数,你转发声明类。

class B;  // DECLARE class B but don't define its contents

class A { // ... uses B as above
};

class B { // ... now you define the class.
};

请参阅C++ FAQ section 39