Я строю моделирование молекулярной динамики с нуля, чтобы попрактиковаться в новых навыках c ++, и у меня возникли некоторые проблемы.
Внутри объекта имитации ‘box’ у меня есть приватная переменная L, которая содержит длину системы.
Также внутри объекта ‘box’ у меня есть вектор объектов ‘частиц’ (никак не получен из ‘box’). Объект «частицы» содержит нормализованное положение частицы (от 0 до 1 в каждом измерении).
Мне нужен способ доступа к L изнутри объекта ‘частиц’. Мне нужно это, чтобы я мог использовать ее для умножения нормализованной позиции, чтобы получить реальную позицию, когда это необходимо (нормализованная позиция удобнее работать с большей частью времени).
Этот доступ к L должен быть только для чтения и не генерировать копию L, а скорее, все частицы должны ссылаться на один и тот же L в случае его изменения (например, поле расширяется).
Я подумал о том, чтобы передать каждому объекту «частицы» постоянную ссылку на L, когда они инициализируются.
Это действительно лучший способ?
Есть ли способ сделать это, не включающий передачу чего-либо каждому объекту «частица» в его конструкторе? (потому что мне, возможно, придется передавать еще много таких «переменных состояния» каждой «частице»)
Благодарю.
Редактировать: я прилагаю код и обращаюсь к предложению @ 1201ProgramAlarm, которое, кажется, имеет смысл, но у меня были проблемы с реализацией:
Particle_Class.h
class Box_Class;
class point;
class Particle_Class
{
public:
Particle_Class(Box_Class &box);
private:
const Box_Class &box;
point velByL;
};
Particle_Class.cpp
Particle_Class::Particle_Class(Box_Class &box)
:box(box){}
void Particle_Class::init_P(const point pt){velByL=pt*box.get_L()/mass; return ;};
Box_Class.cpp
for (int i=0;i<initN;i++)
particle.emplace_back(*this);
К сожалению, я получаю ошибку компилятора в строке void Particle_Class :: init_P
«ошибка: недопустимое использование неполного типа ‘const class Box_Class’ |»
Вы можете передать указатель на box
возражать против particle
объекты и предоставляют метод получения в box
за L
, Этот указатель может быть передан в конструктор particle
и хранятся в объекте, или могут быть переданы в функции-члены particle
что нужен доступ к нему.
поскольку particle
имеет только нормализованное положение, что определяет фактическое положение частицы box
, Так что ваши box
У объекта должен быть метод для возврата реальной позиции данной частицы:
struct Particle { float x, y; /* maybe other properties */ };
struct Position { float x, y; };
struct Box {
Position position(Particle const& p) {
return {p.x * L, p.y * L};
}
private:
float L;
};
Таким образом, вам не нужно particle
использовать box
и тебе не нужно particle
чтобы получить доступ к приватному члену ящика, и вам не нужен аксессор.
Будет ли частица, зная, что это реальная позиция лучше?
Ответ — нет. Частица не должна знать, в каком положении она находится.
Допустим, у вас есть куча частиц, которую вы хотите нарисовать в рамке, тогда вам понадобится не только частица, но и коробка. Но частица сама по себе не нуждается в коробке.
Это также упрощает перемещение частицы из одного блока в другой: вам нужно только отправить другой блок в функцию рисования и / или переместить вектор частицы в вектор другого блока. Нет копирования, не меняются ссылки, нет проблем.
Вы можете создать метод получения в коробке, чтобы разрешить доступ к L. Это может выглядеть примерно так
public:
int GetL(){
return L;
}
Затем, ваш particle
объекты вызывают этот метод, чтобы прочитать значение L.
Если публичный доступ к L нежелателен (возможно, по соображениям безопасности), вы можете объявить частицы как друга. Это особенность C ++, которая позволяет частицам напрямую закрывать члены box. Некоторые люди считают «друга» плохой практикой кодирования. Это также приводит к шуткам о том, что друзьям разрешен доступ к частным пользователям.
friend particles[];
Если я вас правильно понимаю, L является частной частью вашей реализации, и вы не хотите показывать публичный метод получения в вашем интерфейсе.
Одно из решений, которое я использовал в прошлом, — это создание вспомогательного класса, который отображает общее состояние двух классов — в этом случае он может называться BoxParticleInterface.
Интерфейс может быть создан Box и передан Particle на стадии разработки.
class BoxParticleInterface
{
BoxParticleInterface( L const & l, Etc const & etc ) : l_( l ) { }
L const & l() { return l_; }
L l_;
}
Это может быть более полезным, чем передавать одну ссылку / указатель в этом:
а) логически группирует элементы, которые передаются из коробки в частицу, и
б) немного легче расширить, если у вас есть больше состояний, которые вы хотите общаться.