위로 돌아 가기 '98 내 이전 NeXT를 교체 한 후 objective-c에서 C++로 화학 모델을 변환했지만 실제로는 을 배울 수있는 기회를 얻지 못했습니다. C++. 지금은 컨테이너를 사용하는 방법을 배우는 것을 의미하는 현대적인 C++로 코드를 다시 작성합니다. 스마트 포인터 및 템플릿.참조로 반환 된 참조로 반환 된 C++ 벡터에 대한 참조를 저장하려고 시도했습니다.
출력 변수를 각 시간 단계가 아니라 앞면에서 한 번만 구문 분석해야하므로 원래 출력 변수 포인터 (float ***outVars
)의 포인터 배열을 생성했습니다. 각 시간 간격 후에 포인터 목록을 실행할 수 있으며 outVars
이 원래 데이터를 가리키고 있기 때문에 항상 모델의 현재 상태를 제공합니다.
코드를 행렬의 행렬에서 벡터 행렬로 변경하고 있습니다. 원래 벡터에 대한 참조가 아닌 벡터 사본 만 반환 할 수있었습니다. 벡터를 수정하고 싶지는 않습니다. 직접 읽기 액세스 만하면됩니다.
아직 온라인 답변을 찾지 못했다고 생각합니다. 내가 온라인으로 찾은 대부분은 단지 참조 용으로 돌아 가기 위해 std::vector<float> &
을 사용한다고 말했지만 분명히 작동하지 않는다.
참조가 아닌 값 (변수라고 가정)을 복사 할 것이므로 하나의 메모를 보았 기 때문에 fvec2D &outVar2D;
(아래 헤더 파일 참조)을 시도했습니다.
저는 const를 사용하거나 사용하지 않으려 고 노력했지만 차이점이 없습니다.
나는 vector.data()
을 돌려 보았지만 새로운 벡터에 할당하는 것도 복사했습니다. .data()
메모리 블록에 대한 포인터를 유지하는 것은 원래 벡터의 크기를 조정해야하는 경우 매우 나쁜 생각입니다.
std::shared_ptr
에서 벡터를 래핑하려고 시도했지만 shared_ptr에서 각 치수 벡터를 래핑 할 필요가 있음을 알았습니다.이 벡터는 지나치게 성가신 사실을 빠르게 나타냅니다.
나는 vector::iterator
을 반환하는 제안을 보았습니다. 아직 그 일을 할 수 없었습니다. 어쩌면 2D 데이터를 얻는 것이 그 길을 걷고 있습니다. 나는 iterator를 검사 할 때 충돌없이 실행되도록 노력하고있다.
1D 배열을 사용하면이 문제를 해결할 수 있을지 모르지만 수백만 개의 호출에 대한 모든 색인 참조를 계산하는 것이 차선책으로 보입니다. std::array
도 사용하는 것으로 생각했지만 벡터가 가장 간단한 변환으로 보입니다. 아마 나는 그것을 재고해야한다.
누구든지이 작업을 수행하는 방법에 대한 제안 사항이 있으면 알려 주시면 감사하겠습니다.
클래스 화학은 - 원래 행렬을 concentration
class chem
{
public:
typedef std::vector<float> fvec1D;
typedef std::vector<std::vector<float> > fvec2D;
chem(int xstep, int zstep) : concentration(xstep, fvec1D(zstep, 1.5)) {}
...
const fvec2D &getConc() const { return concentration; }
const fvec1D &getConc(int x) const {return concentration[x]; }
private:
fvec2D concentration;
};
클래스 모델을 관리 - 요구 chem::concentration
class model
{
public:
typedef std::vector<float> fvec1D;
typedef std::vector<std::vector<float> > fvec2D;
...
private:
fvec2D null2D {{0.0}};
fvec1D null1D {0.0};
fvec2D &outVar2D;// = null2D; // tried this and at ctor
fvec1D &outVar1D;// = null1D;
std::vector<std::unique_ptr<chem> > chemList;
};
model::model() : outVar2D(null2D), outVar1D(null1D)
{
outVar2D = chemList[0]->getConc(); // or
outVar1D = chemList[0]->getConc(1);
}
void model::plot()
{
for (int z=0; z<numZSteps; ++z) {
std::cout << outVar1D[z];
std::cout << outVar2D[1][z];
}
}
void model::run()
{
plot(); // produces init concentration of 1.5 at each z
chemList[0]->changeConc(); // Changes values in concentration
plot(); // STILL produces init conc of 1.5 at each z
}
TMI. 원하지 않는 동작을 보여줄 수있는 코드를 12 줄 이상 줄이십시오. –
감사합니다. @ 샘. 내가 너무 멀리/충분하지 않은지 알려줘. – psimpson
이것은 실제 코드가 아닌 가짜 코드이거나 깨진 C++ 컴파일러를 사용하고 있습니다. 그림과 같이 자기 존중 C++ 컴파일러는 컴파일하지 않습니다. 클래스에 참조 인 멤버가 있으면 생성자에서 초기화해야합니다. 'model :: model()'은 두 개의 참조 멤버를 초기화하지 못합니다. 생성자 본문의 할당은 초기화가 아닙니다 (초기화되지 않은 참조를 할당하여 메모리가 손상되어 결국 임의의 충돌이 발생합니다). 당신 사본이 있어요. –