где в этом коде вызывается оператор присваивания? - PullRequest
0 голосов
/ 09 декабря 2011

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

Мне фактически говорят, что строка, которая пытается вызвать оператор =, - это std::vector<Bullet> bullets в следующем коде. Я просто не понимаю, где вызывается оператор присваивания и почему он вызывается. Нигде я не делаю что-то вроде Bullet bullet1 = bullet2;

РЕДАКТИРОВАТЬ - а также, почему не подходит оператор присваивания по умолчанию? У меня нет членов указателя в иерархии Bullet.

Спасибо за помощь.

#ifndef GUN_H
#define GUN_H

#include "gameObject.h"
#include "Bullet.h"
#include <vector>

class Mesh;

class Gun : public GameObject
{  
    private:
        std::vector<Bullet> bullets; // this line right here

protected:
        virtual void TriggerPulled() = 0;

public:
        Gun(Mesh& mesh);

        virtual ~Gun();

    std::vector<Bullet>& Bullets();
};

#endif

это источник для того же файла:

#include "Gun.h"
#include "Mesh.h"

Gun::Gun(Mesh& mesh) : GameObject(mesh)
{
    bullets = std::vector<Bullet>();
}

Gun::~Gun() {}

std::vector<Bullet>& Gun::Bullets()
{
return bullets;
}

это пуля:

#ifndef BULLET_H
#define BULLET_H

#include "BoundingSphere.h"
#include "helperMethods.h"
#include "GameObject.h"

class Bullet : public GameObject
{
private:
float velocity;
float distance;
D3DXVECTOR3 firedFrom;
BoundingSphere bSphere;

public:
Bullet(D3DXVECTOR3 position, D3DXVECTOR3 rotation, float velocity, D3DXCOLOR colour, Mesh&  mesh);
~Bullet();

BoundingSphere& BulletSphere();
};

#endif

BoundingSphere:

#ifndef BOUNDING_SPHERE_H
#define BOUNDING_SPHERE_H

#include <d3d10.h>
#include <d3dx10.h>

class Ray;
class BoundingBox;

class BoundingSphere
{
private:
D3DXVECTOR3 centre;
float radius;
public:
BoundingSphere(D3DXVECTOR3 position, float radius);
BoundingSphere();
bool Intersects(BoundingSphere boundingSphere);
bool Intersects(BoundingBox boundingBox);
bool Intersects(Ray ray, D3DXVECTOR3& result);

// getters
const D3DXVECTOR3 Centre();
const float Radius();

// setters
void BoundingSphere::Centre(D3DXVECTOR3 centre);
};

#endif

геймобжекты:

#ifndef GAMEOBJECT_H
#define GAMEOBJECT_H

#include <d3d10.h>
#include <d3dx10.h>

class Mesh;

class GameObject 
{
private:
D3DXVECTOR3         scale;
D3DXVECTOR3         rotation;
D3DXVECTOR3         position;
D3DXCOLOR           colour;

D3DXMATRIX matFinal;

Mesh& mesh;

protected:
void Draw(D3DMATRIX matView, D3DMATRIX matProjection);

public:
    GameObject(Mesh& mesh);
virtual ~GameObject();

//getters
const D3DXVECTOR3   Scale();
const D3DXVECTOR3   Rotation();
const D3DXVECTOR3   Position();
const D3DXCOLOR     Colour();

//setters
void Scale(D3DXVECTOR3 scale);
void Rotation(D3DXVECTOR3 rotation);
void Position(D3DXVECTOR3 position);
void Colour(D3DXCOLOR colour);
};

#endif

Ответы [ 3 ]

2 голосов
/ 09 декабря 2011

GameObject (и, следовательно, все его производные) содержит ссылку на Mesh. Ссылки инициализируются при построении и не могут быть переназначены, поэтому в этом случае компилятор не сгенерирует оператор присваивания по умолчанию.

1 голос
/ 09 декабря 2011

Во-первых, причина, по умолчанию operator= не генерируется, заключается в том, что GameObject содержит ссылку (Mesh& mesh).Компилятор не генерирует operator= для классов, которые содержат одну или несколько ссылок, а также для классов, базовый класс которых не имеет operator=.

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

Вопрос в том, действительно ли вы хотите копировать эти объекты.Я просто догадываюсь по именам, но они звучат как объекты, которые имеют идентичность или будут идентичны после завершения кода.Например, если вы измените положение Bullet, вам не нужно отслеживать все копии, а также изменять их в них - у Bullet есть личность.

Решение состоит в том, чтобы использовать std::vector<Bullet*> и динамически распределять все Bullet (и все остальное, что происходит из GameObject).Что, если вы думаете об этом, является нормальным: ваши объекты имеют время жизни, которое определяется развитием игры, и не зависят от объема или в значительной степени от срока службы любого другого объекта.Bullet может быть исключением, так как если Gun, содержащий их, уничтожен, то Bullet в нем, вероятно, также должен быть уничтожен.Но я бы все-таки отнесся к этому более обобщенным образом: деструктор Gun позаботился о разрушении его Bullet.В более общем случае, однако, когда объект уничтожается, вам нужно будет найти все другие объекты, которые ссылаются на него, и удалить их указатели на него.Как правило, для этого требуется что-то вроде шаблона наблюдателя - мне еще предстоит увидеть какой-либо умный указатель, который обрабатывает это правильно.

1 голос
/ 09 декабря 2011

В источнике у вас есть:

bullets = std::vector<Bullet>();

Оператор по умолчанию = не будет работать, потому что GameObject имеет ссылочный элемент mesh, который нельзя назначить.(Это почти как указатель. Он содержит адрес фактического класса или структуры)

...