Конструктор копирования вызывает бесконечный цикл - PullRequest
2 голосов
/ 28 января 2010

Я передаю значение для копирования конструктора в качестве ссылки, но вызывается бесконечный цикл.

Вот мой класс:

class Vector2f{
private:
    GLfloat x;
    GLfloat y;

public:
    Vector2f();
    Vector2f(const GLfloat _x, const GLfloat _y);
    Vector2f(const Vector2f &_vector);

    ~Vector2f();
};

Вот реализация методов:

Vector2f::Vector2f():
        x( 0.0f ),
        y( 0.0f )
{
    DebugLog("Vector2f constructor");
}

Vector2f::Vector2f(const GLfloat _x, const GLfloat _y):
        x( _x ),
        y( _y )
{
    DebugLog("Vector2f constructor(%f, %f)", _x, _y);
}


Vector2f::Vector2f(const Vector2f &_vector):
        x( _vector.getX() ),
        y( _vector.getY() )
{
    DebugLog("Vector2f copy constructor");
}

Vector2f::~Vector2f()
{

}

Вот как я получаю доступ к классу:

Vector2f tempVector1 = Vector2f(0.0f, 0.0f);
DebugLog("tempVector1 initialized");

Vector2f tempVector2;
tempVector2 = Vector2f(0.0f, 0.0f);
DebugLog("tempVector2 initialized");

Результаты, которые я получаю:

Vector2f constructor(0.000000, 0.000000)
tempVector1 initialized
Vector2f constructor
Vector2f constructor(0.000000, 0.000000)
Vector2f copy constructor
Vector2f copy constructor
Vector2f copy constructor
...

Бесконечный цикл происходит при попытке инициализации ранее созданного объекта. Если я попытаюсь скопировать tempVector1 в tempVector 2, также произойдет бесконечный цикл:

Vector2f tempVector2;
tempVector2 = Vector2f(tempVector1);

Почему это происходит и как я могу предотвратить его попадание в бесконечный цикл?

Заранее спасибо.

Ответы [ 4 ]

6 голосов
/ 28 января 2010

Эта строка:

tempVector2 = Vector2f(tempVector1);

будет вызывать оператор =, а не конструктор копирования. Вы определяете оператора, который делает что-то дурацкое?

Кроме того, ваш код работал нормально для меня с g ++ 4.3.2 на Linux и g ++ 4.2.1 на Mac (после того как я определил getX, getY, преобразовал DebugLog в printf и использовал float вместо GLfloat).

1 голос
/ 28 января 2010

Во втором случае вы выполняете задание, а не строительство. Вы не определили свою собственную версию оператора копирования-назначения, что означает, что компилятор предоставит ее вам. Предоставленный компилятором оператор присваивания копии будет неявно объявлен как

Vector2f& operator =(const Vector2f& rhs);

Обратите внимание, что единственный параметр этого оператора имеет тип "ссылка на константу".

В вашем коде вы настаиваете на предоставлении временного значения объекта типа Vector2f в правой части назначения.

tempVector2 = Vector2f(0.0f, 0.0f);

Это означает, что ссылочный параметр operator = инициализируется временным значением типа класса. В соответствии со спецификацией языка (8.5.3 / 5), компилятору разрешено копировать этот временный объект столько раз, сколько ему нужно, прежде чем фактически присоединить ссылку. В конце концов он должен прекратить копирование и, наконец, вызвать оператора. Обычно компилятор не сходит с ума от копирования (большинство из них вообще не копируют), однако в вашем случае это кажется проблемой. По какой-то причине ваш компилятор блокируется в бесконечном цикле копирования, никогда не останавливая его. Я не знаю, что вызывает это. Может быть ошибка в компиляторе.

Обратите внимание, что даже в

tempVector2 = Vector2f(tempVector1);  

вы все еще предоставляете правую часть в виде временного значения. Значение r является результатом явного приведения к Vector2f, который вы по какой-то причине поместили туда. Я понятия не имею, почему ты это сделал. Если проблема действительно в компиляторе (а не в коде, который вы нам не показываете), я уверен, что если вы просто сделаете

tempVector2 = tempVector1;  

задание будет выполнено без проблем. Вот как вы можете обойти эту проблему, если она окажется ошибкой в ​​компиляторе: прекратите использовать временные символы в качестве аргументов оператора копирования и копирования-назначения.

1 голос
/ 28 января 2010

Я думаю, что проблема в вашем операторе присваивания. Как выглядит оператор =

Кажется, что оператор = называет себя как-то. Возможно ли, что фрагмент кода взят из тела оператора = сам?

Если это так, то решение состоит в том, чтобы изменить код (внутри оператора =) так, чтобы он использовал копию ctor. Каноническая форма выглядит следующим образом:

Vector2f temp = Vector2f(arg);
swap(*this, temp)   // You need to implement a swap method
return *this; 

(См. Исключительный C ++ Хербом Саттером для более подробной информации)

0 голосов
/ 19 февраля 2010

Запустите его под IDE. Когда он в цикле, нажмите кнопку «Пауза». Вы увидите точно, в чем проблема. Вот почему.

...