同一类的两个对象互相引用

时间:2018-08-06 09:27:06

标签: c++

相同类型的对象总是成对出现。它们永远不会孤独,它们永远不会超过两个,就像纠缠的粒子一样。

我想用同一类的两个实例互相引用在C ++中实现此问题。创建主实例会自动创建辅助实例:

#include <iostream>
using namespace std;

class Particle
{
    public:
    // Constructs primary instance
    Particle() :
    partner_(Particle(*this))
    {
        cout << "Hi, I'm primary." << endl;
    }

    private:
    // Constructs secondary instance
    Particle(Particle & partner) :
    partner_(partner)
    {
        cout << "Hi, I'm secondary." << endl;
    }

    Particle & partner_;
};

int main()
{
   Particle two_friends;

   return 0;
}

无法编译:

main.cpp: In constructor ‘Particle::Particle()’:
main.cpp:10:14: error: cannot bind non-const lvalue reference of type ‘Particle&’ to an rvalue of type ‘Particle’
     partner_(Particle(*this))
              ^~~~~~~~~~~~~~~

是否可以使用引用来解决此问题?还是必须使用指针?

2 个答案:

答案 0 :(得分:1)

您的系统中存在一个巨大的问题,第一个在堆栈上创建的粒子是实时的,但是第二个又如何呢?在您的代码中,它是作为temp变量创建的,并在构造函数中销毁了,因此在类内部进行引用是毫无用处的。我认为您应该做的是在另一个包装上使用std :: pair并自己设置伙伴,例如

struct ParticlePair{
    Particle first;
    Particle second;
    ParticlePair()
    {
        first.setPartner( second );
        second.setPartner( first );
    }
}

最好将“粒子”构造函数设为私有,并将“粒子对”声明为朋友,在这种情况下,您将无法单独创建“粒子”。

如果您尝试使用指针,则还有另一个问题:如何正确删除?首先删除应先删除第二个,但这意味着第二个删除也应首先删除。迟早您将删除已删除的指针或删除在堆栈上创建的对象。

答案 1 :(得分:1)

之所以无法编译,是因为编译器使您免于犯错,并且不允许将临时对象传递给函数(或构造函数),因为这可能会导致错误。在您的情况下,您的临时对象将在构造函数的末尾被销毁,并且您只有一个粒子带有悬空引用,该引用指向现在已销毁的另一个对象。

一种解决方案是使用共享指针和弱指针(您需要弱指针或有循环引用)。

#include <memory>

class Particle
{
public:
    static std::shared_ptr< Particle > create()
    {
        std::shared_ptr< Particle > first( new Particle() );
        std::shared_ptr< Particle > second( new Particle() );
        // first will own second
        first->partner = second;
        // second will have a weak pointer to first
        second->weakPartner = first;
        return first;
    }

    std::shared_ptr< Particle > getPartner()
    {
        if (partner)
        {
            return partner;
        }
        return weakPartner.lock();
    }

private:
    Particle() {};
    std::shared_ptr< Particle > partner;
    std::weak_ptr< Particle > weakPartner;
};

int main()
{
  std::shared_ptr< Particle > two_friends = Particle::create();
}

对第一个粒子保持shared_ptr可使第二个粒子保持活动状态,但请注意,如果对第二个粒子只有shared_ptr,则第一个粒子将被销毁。您可以通过不使用weak_ptr来避免这种情况,但是在破坏粒子之前,您必须手动中断shared_ptr循环。