shared_ptr 사용중 자료구조(vector) 관련 문제...

dorado2의 이미지

기존에 사용하던 코드 대신에 boost::shared_ptr 을 써서
자료구조를 다시 정의해서 쓰려고 하고 있습니다.

#include <vector>
#include <iostream>

#include <boost/variant.hpp>
#include <boost/smart_ptr.hpp>

class NP;

enum NPType { ADDR_NP, ROUTER_ADDR_NP };


typedef boost::shared_ptr<NP> NPPtr;        // NP 클래스의 포인터 타입을 boost::shared_ptr 을 이용해서 사용
typedef std::vector<NPPtr> CNPObList;       // NPPtr 타입을 담는 vector 정의


// boost::variant 를 이용해서 여러 가지 데이터 타입을 담을 수 있는 타입 선언
typedef boost::variant<bool, unsigned char, signed char, unsigned short, signed short, unsigned int, signed int, float> varType;
typedef std::vector<varType> NPDATA;



class SimpleNode{

public:
	SimpleNode();
	SimpleNode(const SimpleNode &);   // copy constructor
	virtual ~SimpleNode();
		
protected:
	CNPObList NPList;

public:
	void InitNP();
	void ResetNP();
	CNPObList getNPList() {return NPList;};	
}

class NP{

public:
	NP();
	NP(const NP &);

	NP(NPType npType, unsigned short nId, unsigned char nTp, unsigned short nL, NPDATA nData);

	virtual ~NP();

	unsigned short getNpIndex() const {return npIndex; };
		 
private:

	NPType n_DefNPType; 
	CString NPName;

	unsigned short npIndex;
	unsigned char npType;
	unsigned short npArrayLength;
	NPDATA npData;

};

뭐 간단히 추려보면 대략 위와 같은 형태로 선언을 해서 쓰고 있구요. SimpleNode class안에 CNPObList 변수를 선언해서 사용합니다. 그런데, 초기화 코드안에서 CNPObList 변수인 NPList 내에 특정 값들(NP 클래스)를 넣어주어야 합니다. 그 코드는 아래와 같구요.

void SimpleNode::InitNP()
{
	if( getNPList().empty() == true)
	{
		NPDATA nData;
		varType a;

		// Addr NP
		a = (unsigned char)0x00;
		nData.push_back(a);
		nData.push_back(a);		
		NPPtr p(new NP(ADDR_NP, 0x4000, NP_UNSIGNED | NP_CHAR, 2, nData));       		                NPList.push_back(p);
	
		nData.clear();
		a = (unsigned char)0x00;
		nData.push_back(a);
		
		p.reset(new NP(ROUTER_ADDR_NP, 0x4001, NP_UNSIGNED | NP_CHAR, 1, nData));       
		NPList.push_back(p);           // 이건 들어감
	
		....
		
		getNPList().push_back(p);  // 이러면 안 들어감


		CNPObList tmp = getNPList();
		tmp.push_back(p);                    // 이것도 역시 안 들어감

		NPPtr c = getNPList().at(0);       // 데이터 읽어오는 것은 가능함
		unsigned short b = c->getNpIndex();
		
		}
}

문제는 위에서 보듯이 NPList를 바로 써서 NPList.push_back(p)라고 해주면 vector에 바로 들어가는데,

getNPList().push_back(p) 이런 식으로 getNPList()를 통해 얻어온 vector에는 NPPtr 타입인 p가 제대로 들어가지 않는 문제가 생깁니다. 저로서는 이해가 잘 안 되는데요.

반면 위 코드 마지막 부분에서 보듯이, 데이터를 읽어올 때는 getNPList() 도 동작이 됩니다.

getNPList() 함수가 const도 아닌데, 왜 저런지 모르겠네요.

비슷한 문제가 다른데서도 발생합니다.

void SimpleNode::ResetNP()
{
	int size;
	
	getNPList().clear();
	size = getNPList().size();
	
	NPList.clear();
	size = NPList.size();
}

단순히 NPList vector에 담긴 element를 모두 지우는 부분인데요.

getNPList().clear() 하면 내용이 지워지질 않습니다. 즉 size가 0이 아니라 그대로입니다.

반면 NPList.clear()은 잘 동작하는군요.

어떤 것이 이유가 될 수 있을지요?

doldori의 이미지

CNPObList getNPList() {return NPList;}; 이것 때문에 그렇습니다. getNPList()가 반환하는 것은 this->NPList의 복사본입니다. 복사본에 push_back()을 해도 this->NPList에는 아무 변화가 없게 되지요. 참조형으로 반환하면 됩니다.

dorado2의 이미지

doldori wrote:
CNPObList getNPList() {return NPList;};
이것 때문에 그렇습니다. getNPList()가 반환하는 것은 this->NPList의 복사본입니다.
복사본에 push_back()을 해도 this->NPList에는 아무 변화가 없게 되지요.
참조형으로 반환하면 됩니다.

어이쿠, 이런.... :oops:

간단한 실수를...

답변 감사드려요.

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.