#include <iostream>
#include <vector>
using namespace std;
class A {
private:
int number;
public:
A() {number = 0;}
A(int nr) {number = nr;}
//A(const A& rhand) {this->number = rhand.number;}
int get_number() const {return this->number;}
A& operator=(const A& rhand) {
this->number = rhand.number;
return (*this);
}
};
class B {
private:
vector<A*>* content;
vector<A*>::iterator currA;
bool currA_valid;
public:
B() {
content = new vector<A*>;
currA = content->begin();
currA_valid = false;
}
void push_A(A* nA) {content->push_back(nA); currA_valid = false;}
void push_A(A nA) {content->push_back(&nA); currA_valid = false;}
A get_A() {
if(!currA_valid) {
currA = content->begin();
if(!content->empty()) {
currA_valid = true;
}
}
if(currA == content->end() || this->content->empty()) {
currA = content->begin();
return A();
}
else {
A result(**currA);
++currA;
return result;
}
}
};
int main()
{
B container;
A* a1 = new A(1);
cout << a1->get_number() << endl;
A a2(2);
cout << a2.get_number() << endl;
container.push_A(a1);
container.push_A(a2);
A tmp;
while((tmp = container.get_A()).get_number() != 0)
cout << "Inhalt tmp: " << tmp.get_number() << endl;
return 0;
}
최근에 나는이 코드 스 니펫으로 바뀌 었습니다.왜이 복사 생성자가 필요한가
본질적 클래스 B는 실제 코드 A의 클래스 A.
물체 컨테이너 훨씬 크다이며 타입 A의 동일한 오브젝트 공간을 절약하기 위해 컨테이너에 여러 번 정도 나타나는, B는 A에 대한 포인터 만 저장합니다.
B :: push 함수는 A 유형의 객체를 컨테이너에 공급합니다.
그들은 A.
주요 기능의 끝에있는 동안 루프의 포인터와 값 과부하 난 (가지 iostream 개체에 사용되는 스트리밍 연산자 등) 원하던.
B의 반복자 "currA"는 B :: get_A() 함수 호출에서 마지막으로 반환 된 요소를 추적하므로 해당 함수를 연속적으로 호출하면 B의 모든 A 객체가 끝날 때까지 반환됩니다 에 도달했습니다. 이 경우 내부 반복자가 재설정되고 내부 무효화 플래그 (이 경우 A :: number가 단순함)가있는 객체 A가 반환됩니다.
이 프로그램의 출력은 다음과 같을 수있다 :
는1
2
Inhalt tmp: 1 //content of a1
Inhalt tmp: 4620996 //content of a2
주요 기능은 두 개체 ± 1 (1)에서 A * (A2)의 인스턴스 (2).
A :: get_number()를 테스트하려면 내부 값이 모두 표시되어야합니다. 둘 다 예상대로 작동합니다. 그러나 컨테이너에 두 가지를 모두 넣은 다음 다시 가져온 후에는 a1 만 제대로 표시됩니다. a2의 내용은 임의의 난수를 보여줍니다.
먼저 생각에서, 나는 포인터의 일부 실수를하지만, 하나는 선언하면 문제가 해결 될 것을 증명과 같은 클래스 A의 복사 생성자 정의 : 지금까지
A(const A& rhand) {this->number = rhand.number;}
을 필자는 복사 생성자가 제공되지 않는다면 C++ 컴파일러에 의해 암시 적으로 정의되며, 클래스가 얕은 복사본을 피하기 위해 포인터를 멤버로 가질 때이를 구현하는 것이 좋습니다. 그러나이 경우 A는 int 만 갖는다.
또한 B :: get_A()를 제거하고 다른 방법으로 컨테이너 내용을 가져 와서 코드를 단순화하려고했습니다. 문제는 기본 생성자를 구현하지 않아도 사라졌습니다. 내 질문은 여기에 있습니다 :
1.) 내가 제공 한 것과 유사한 컴파일러 생성자가 컴파일러에 정의되어 있지 않습니까?
2) 복사 생성자는 실제 문제와 어떤 관련이 있습니까? 복사 생성자를 구현하면 문제가 어떻게 해결됩니까?
클래스 내 애트리뷰트를 초기화하기 위해 바디 내 assigments 대신 초기화 목록을 사용하십시오. – Manu343726
'push_back'의 두 번째 오버로드에서 argumment의 로컬 복사본에 대한 포인터를 저장하고 있으므로 push_back이 끝난 후에는 해당 포인터가 유효하지 않습니다. – Manu343726