2017-02-08 8 views
2

Я создаю моделирование молекулярной динамики с нуля, чтобы попрактиковаться в своих новых навыках C++, и у меня возникли некоторые проблемы.Доступ к переменной класса из объектов, входящих в один класс

Внутри объекта «box» моделирования у меня есть частная переменная L, которая содержит длину системы. Также внутри объекта «ящик» у меня есть вектор объектов «частиц» (не полученный каким-либо образом из «окна»). Объект «частицы» содержит нормализованное положение частицы (от 0 до 1 в каждом измерении). Мне нужен способ доступа к L изнутри объекта «частицы». Мне нужно это, чтобы я мог использовать его, чтобы умножить нормализованное положение, чтобы получить фактическое положение, когда это необходимо (нормализованное положение удобнее работать в большинстве случаев).

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

Я думал о том, что, возможно, переходя к каждому объекту частицы, является константной ссылкой на L, когда они инициализируются. Действительно ли это лучший способ? Есть ли способ сделать это, который не связан с передачей чего-либо каждому объекту «частицы» в его конструкторе? (потому что мне, возможно, придется передать еще много таких «переменных состояния» каждой «частице»)

Спасибо.

Edit: Я прилагаю код и решение @ предложение 1201ProgramAlarm «s, который, кажется, имеет смысл, но у меня были проблемы, реализующие:

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); 

К сожалению, я получаю ошибку компиляции на линии недействительных Particle_Class :: init_P

"Ошибка: неправильное использование неполного типа 'Const класса Box_Class' |"

+0

Можете ли вы включить свой код в свой пост? Это может облегчить вам получение ответа. – RGA

ответ

1

Вы можете передать указатель на объект box объектам particle и предоставить метод геттера в box для L. Этот указатель может быть передан конструктору particle и сохранен внутри объекта или может быть передан в функции-члены particle, которым необходим доступ к нему.

+0

Я не думал передавать ссылку на объект box, вместо того, чтобы передавать ссылки на каждый параметр состояния на своем собственном. Отлично, это должно сработать. –

+0

Но теперь у меня проблемы с реализацией. Я получаю ошибку: недопустимое использование неполного типа 'const class Box_Class (см. Отредактированный пост) –

+0

@YoavPollack Похоже, вам нужно включить заголовок Box_Class в particle_class.cpp. – 1201ProgramAlarm

0

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

public: 
    int GetL(){ 
     return L; 
    } 

Тогда ваши particle объекты называют этот метод, чтобы прочитать значение L.

Если публичный доступ к L нежелателен (возможно, по соображениям безопасности), вы можете объявить частицы как друга. Это C++-функция, которая позволяет частицам непосредственно частным членам коробки.Некоторые считают «друга» плохой практикой кодирования. Это также приводит к шуткам о том, что друзьям разрешено пользоваться частными членами.

friend particles[]; 
0

Если я правильно понять вас, L является частной частью реализации, и вы не хотите подвергать публичный геттер в интерфейсе.

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

Интерфейс может быть создан коробкой и передан в конструкцию Particle.

class BoxParticleInterface 
{ 
    BoxParticleInterface(L const & l, Etc const & etc) : l_(l) { } 
    L const & l() { return l_; } 
    L l_; 
} 

Это может быть более полезным, чем мимолетный один опорный/указатель вокруг в том, что:
а) логически группирует члены, которые передаются от Box для частиц и
б) это немного легче если у вас больше состояний, которые вы хотите установить.

1

С 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, чтобы получить доступ к закрытому члену и вам не нужен аксессор.


Будет ли частица знать, что это реальное положение лучше?

Ответ отрицательный. Частице не нужно знать, что это реальное положение.

Предположим, у вас есть куча частиц, где бы вы ни хотели рисовать в коробке, тогда вам понадобится не только частица, но и коробка. Но частица сама по себе не нуждается в коробке.

Это также делает тривиальным перемещение частицы из одной коробки в другую: вам нужно только отправить другое окно в функцию рисования и/или переместить вектор частицы в вектор другого окна. Никаких копий, никаких изменяющихся ссылок, никаких проблем.

+0

Ваше решение кажется лучшим в плане ООП. Однако после рассмотрения я решил не использовать его, поскольку это будет означать использование нормализованных единиц повсюду в классе ящиков, что будет неприятностью и может привести к ошибкам с моей стороны. Спасибо хоть! –

+0

@YoavPollack Вы можете создать обертку вокруг указателя на частицу и указатель на поле с именем 'BoxedParticle', в котором есть' normalized() 'и' real() 'accessors, и передать эту оболочку, где вам нужны частицы с их реальным положением ,Он даже имеет потенциал быть быстрее и эффективнее памяти, а также имеет все преимущества моего решения. –

 Смежные вопросы

  • Нет связанных вопросов^_^