프로그램 공부하다가 에러가 쉽게 잡히질 않습니다.
글쓴이: nayana / 작성시간: 일, 2004/09/19 - 6:17오후
나름대로 책보면서 공부하고 있습니다.
예제문제를 풀어볼려고 만들고 있는데..에러가 쉽게 잡히질 않습니다.
Array.cpp
1 #include <iostream> 2 3 #include "Array.h" 4 5 template < class Datatype > 6 Array< Datatype >::Array( int p_size ) 7 { 8 // 뉴를 이용하여 배열 크기에 충분한 메모리를 할당하고 그공간의 시작 주소를 m_array에 넣는다. 9 m_array = new Datatype[ p_size ]; 10 11 for ( int i = 0; i < p_size; ++i ) 12 m_array[ i ] = i + 1; 13 14 m_size = p_size; 15 } 16 17 template < class Datatype > 18 Array< Datatype >::~Array() 19 { 20 // 배열이 널값이 아니라면 지운다 21 if ( m_array != 0 ) 22 { 23 delete [] m_array; 24 // 포인터 초기화 25 m_array = 0; 26 } 27 28 } 29 30 template < class Datatype > 31 void Array< Datatype >::Resize( int p_size ) 32 { 33 // new를 이용하여 충분한 메모리 공간 할당후 시작주소를 newarrayㅇㅔ 넣는다. 34 Datatype* newarray = new Datatype[ p_size ]; 35 36 // 동적할당이 돼엇는지 확인 37 if ( newarray == 0 ) 38 return; 39 40 int min; 41 // newarray의 크기가 기존의 것 보다 작다면 42 if ( p_size < m_size ) 43 min = p_size; 44 45 else 46 min = m_size; 47 48 int index; 49 50 // 기존의 배열을 새 배열에 복사 51 for ( index = 0; index < min; ++index ) 52 newarray[ index ] = m_array[ index ]; 53 54 m_size = p_size; 55 56 // 기존 배열 클리어 57 if ( m_size != 0 ) 58 delete [] m_array; 59 60 m_array = newarray; 61 } 62 63 64 // 접근 연산자 기존 배열 의 접근 방식으로 접근 할수 있도록 함 65 // 참조 반환 66 template < class Datatype > 67 Datatype& Array< Datatype >::operator [] ( int p_index ) 68 { 69 return m_array[ p_index ]; 70 } 71 72 73 template < class Datatype > 74 void Array< Datatype >::Insert( Datatype p_item, int p_index ) 75 { 76 // p_index 추가 값을 저장할 위치 77 int index; 78 79 for ( index = m_size - 1; index > p_index; --index ) 80 m_array[ index ] = m_array[ index - 1 ]; 81 82 // 첫번 ?매개변수인 새로 추가할 값 83 m_array[ p_index ] = p_item; 84 } 85 86 template < class Datatype > 87 void Array< Datatype >::Remove( int p_index ) 88 { 89 int index; 90 91 for ( index = p_index + 1; index < m_size; ++m_size ) 92 m_array[ index - 1 ] = m_array[ index ]; 93 94 } 95 96 template < class Datatype > 96 template < class Datatype > 97 int Array< Datatype >::Size() 98 { 99 return m_size; 100 } 101 102 103 // 변환 연산자 ?? 104 template < class Datatype > 105 Array< Datatype >::operator Datatype* () 106 { 107 return m_array; 108 } 109 110 template < class Datatype > 111 bool Array< Datatype >::WriteFile( const char* p_filename ) 112 { 113 FILE* outfile = 0; 114 int written = 0; 115 116 outfile = fopen( p_filename, "wb" ); 117 118 if ( outfile == 0 ) 119 return false; 120 121 written = fwrite( m_array, sizeof( Datatype ), m_size, outfile ); 122 fclose( outfile ); 123 124 if ( written != m_size ) 125 return false; 126 127 return true; 128 } 129 130 template < class Datatype > 131 bool Array< Datatype >::ReadFile( const char* p_filename ) 132 { 133 FIlE* infile = 0; 134 int read = 0; 135 infile = fopen( p_filename, "rb" ); 136 137 if ( infile == 0 ) 138 return false; 139 140 read = fread( m_array, sizeof( Datatype ), m_size, infile ); 141 fclose( infile ); 142 143 if( read != m_size ) 144 return false; 145 146 return true; 147 }
Array.h
1 #ifndef ARRAY_H 2 #define ARRAY_H 3 4 #include <stdio.h> 5 6 template<class Datatype> 7 class Array 8 { 9 public: 10 Array( int p_size ); 11 ~Array(); 12 13 void Resize( int p_size ); 14 Datatype& operator[] ( int p_index ); 15 void Insert( Datatype p_item, int p_index ); 16 void Remove( int p_index ); 17 int Size(); 18 operator Datatype* (); 19 bool WriteFile( const char* p_filename ); 20 bool ReadFile( const char* p_filename ); 21 22 private : 23 Datatype* m_array; 24 int m_size; 25 }; 26 27 #endif
BitArray.cpp
1 #include <cstdlib> 2 #include "BitArray.h" 3 4 void BitArray::GameInit() 5 { 6 7 for ( int index = 0; index < 64; ++index ) 8 { 9 g_playerarray[ index ].m_life = 11 + rand() % 10; 10 g_playerarray[ index ].m_money = rand() % 100; 11 g_playerarray[ index ].m_experience = 0; 12 g_playerarray[ index ].m_level = 1 + rand() % 4; 13 14 } 15 16 g_modifiedstates.SetAll(); 17 } 18 19 void BitArray::SetLife( int p_player, int p_life ) 20 { 21 g_playerarray[ p_player ].m_life = p_life; 22 g_modifiedstates.Set( p_player, true ); 23 } 24 25 void BitArray::SetMoney( int p_player, int p_money ) 26 { 27 g_playerarray[ p_player ].m_money = p_money; 28 g_modifiedstates.Set( p_player, true ); 29 } 30 31 void BitArray::SetExperience( int p_player, int p_experience ) 32 { 33 g_playerarray[ p_player ].m_experience = p_experience; 34 g_modifiedstates.Set( p_player, true ); 35 } 36 37 void BitArray::SetLevel( int p_player, int p_level ) 38 { 39 g_playerarray[ p_player ].m_level = p_level; 40 g_modifiedstates.Set( p_player, true ); 41 } 42 43 bool BitArray::SavePlayer( const char* p_filename ) 44 { 45 int index; 46 FILE* savefile = fopen( p_filename, "wb" ); 47 if( savefile == 0 ) 48 return false; 49 50 for( index = 0; index < 64; ++index ) 51 { 52 if( g_modifiedstates[ index ] == true ) 53 { 54 fseek( savefile, sizeof( Player ) * index, SEEK_SET ); 55 fwrite( &( g_playerarray[ index ] ), sizeof( Player ), 1, savefile ); 56 } 57 } 58 59 g_modifiedstates.ClearAll(); 60 return true; 61 }
BitArray.h
1 #ifndef BITARRAY_H 2 #define BITARRAY_H 3 4 #include "Bitvector.h" 5 #include "Player.h" 6 #include "Array.h" 7 8 9 class BitArray 10 { 11 public : 12 void GameInit(); 13 14 void SetLife( int p_player, int p_life ); 15 16 void SetMoney( int p_player, int p_money ); 17 18 void SetExperience( int p_player, int p_experience ); 19 20 void SetLevel( int p_player, int p_level ); 21 22 bool SavePlayer( const char* p_filename ); 23 24 private : 25 Array< Player > g_playerarray( 64 ); 26 Bitvector g_modifiedstates( 64 ); 27 }; 28 29 #endif
Bitvector.cpp
1 #include <cstdlib> 2 #include <cstdio> 3 #include "Bitvector.h" 4 5 6 Bitvector::Bitvector( int p_size ) 7 { 8 // 언사인드형 포인터 초기화 9 m_array = 0; 10 m_size = 0; 11 // 배열을 해당 크기로 변경 12 //32 13 Resize( p_size ); 14 } 15 16 Bitvector::~Bitvector() 17 { 18 if ( m_array != 0 ) 19 delete [] m_array; 20 m_array = 0; 21 } 22 23 void Bitvector::Resize( int p_size ) 24 { 25 //32 26 unsigned long int* newvector = 0; 27 28 // 비트의 갯수를 받고 인트 사이즈로 변환 29 if ( p_size % 32 == 0 ) 30 p_size = p_size / 32; 31 32 else 33 p_size = ( p_size / 32 ) + 1; 34 35 newvector = new unsigned long int[ p_size ]; 36 37 if ( newvector == 0 ) 38 return ; 39 40 int min; 41 42 // 설정한 p_size값이 0보다 작다면 43 if( p_size < m_size ) 44 min = p_size; 45 else 46 min = m_size; 47 48 // 기존 배열 newvector에 임시 복사 49 for ( int index = 0; index < min; ++index ) 50 newvector[ index ]= m_array[ index ]; 51 52 m_size = p_size; 53 54 if ( m_size != 0 ) 55 delete [] m_array; 56 57 m_array = newvector; 58 } 59 60 // 접근연산자로 조회만 가능 61 bool Bitvector::operator [] ( int p_index ) 62 { 63 // 해당 비트가 있는 배열의 칸을 찾음 64 int cell = p_index / 32; 65 66 // 조회 하고자 하는 비트 67 int bit = p_index % 32; 68 69 // and연산 둘다 일이면 일 아님 0 70 return ( m_array[ cell ] & ( 1 << bit )) >> bit; 71 } 72 73 void Bitvector::Set( int p_index, bool p_value ) 74 { 75 int cell = p_index / 32; 76 77 int bit = p_index % 32; 78 79 // 설정하고 자 하는 값이 1이라면 그 비트를 OR 연산으로 설정 80 if ( p_value == true ) 81 m_array[ cell ] = ( m_array[ cell ] | ( 1 << bit )); 82 83 else 84 m_array[ cell ] = ( m_array[ cell ] & ( ~ ( 1 << bit ) ) ); 85 } 86 87 88 void Bitvector::ClearAll() 89 { 90 for ( int index = 0; index < m_size; ++index ) 91 m_array[ index ] = 0; 92 } 93 94 95 void Bitvector::SetAll() 96 { 97 for ( int index = 0; index < m_size; ++index ) 98 m_array[ index ] = 0xFFFFFFFF; 99 } 100 101 102 bool Bitvector::WriteFile( const char* p_filename ) 103 { 104 FILE* outfile = 0; 105 int written = 0; 106 outfile = fopen( p_filename, "wb" ); 107 if( outfile == 0 ) 108 return false; 109 written = fwrite( m_array, sizeof( unsigned long int ), m_size, outfile ); 110 fclose( outfile ); 111 if( written != m_size ) 112 return false; 113 return true; 114 } 115 116 bool Bitvector::ReadFile( const char* p_filename ) 117 { 118 FILE* infile = 0; 119 int read = 0; 120 121 infile = fopen ( p_filename, "rb" ); 122 if ( infile ==0 ) 123 return false; 124 125 read = fread( m_array, sizeof( unsigned long int ), m_size, infile ); 126 fclose( infile ); 127 if( read != m_size ) 128 return false; 129 130 return true; 131 }
Bitvector.h
1 #ifndef BITVECTOR_H 2 #define BITVECTOR_H 3 4 class Bitvector 5 { 6 public: 7 Bitvector( int p_size ); 8 ~Bitvector(); 9 void Resize( int p_size ); 10 bool operator[] ( int p_index ); 11 void Set( int p_index, bool p_value ); 12 void ClearAll(); 13 void SetAll(); 14 int Size(); 15 unsigned long int GetCell( int p_index ); 16 17 bool WriteFile( const char* p_filename ); 18 bool ReadFile( const char* p_filename ); 19 20 private : 21 unsigned long int* m_array; 22 int m_size; 23 }; 24 25 #endif
Player.h
1 #ifndef PLAYER_H 2 #define PLAYER_H 3 4 class Player 5 { 6 public : 7 int m_life; 8 int m_money; 9 int m_experience; 10 int m_level; 11 }; 12 13 #endif
test.cpp
1 #include <cstdlib> 2 3 #include "Bitvector.h" 4 #include "Array.h" 5 #include "Player.h" 6 7 8 int main ( void ) 9 { 10 11 return 0; 12 }
에러는 다음과 같이 나옵니다.
In file included from BitArray.cpp:2: BitArray.h:25: invalid data member initialization BitArray.h:25: (use `=' to initialize static data members) BitArray.h:26: invalid data member initialization
에러를 보니까..BitArray.h 파일에서
Array< Player > g_playerarray( 64 ); Bitvector g_modifiedstates( 64 );여기서 나는 부분인데...무엇이 잘못되었는지 모르겠습니다.
File attachments:
첨부 | 파일 크기 |
---|---|
player.zip | 10.52 KB |
Forums:
얼핏 보기엔 클래스 선언에서 멤버를 초기화 해서 생기는 에러 같습니다.
얼핏 보기엔 클래스 선언에서 멤버를 초기화 해서 생기는 에러 같습니다.
BitArray의 컨스트럭터에서 초기화 해보세요
답변에 감사드립니다.님의 말씀대로 수정하였더니...다음과 같은 에러가
답변에 감사드립니다.
님의 말씀대로 수정하였더니...다음과 같은 에러가 나옵니다.
음..
BitArray가 멤버로 가지고 있는 g_playerarray가 [] 연산자를 오버로딩하지 않아서 그렇습니다.. []연산자를 오버로딩 하시거나 Array 클래스에서 해당 인덱스의 원소를 접근할수 있는 메소드를 만들어주시면 됩니다.
-------------------------------------------------------------------------------
It's better to appear stupid and ask question than to be silent and remain stupid.
제가 아직 내공이 부족해서인지...구체적으로 어떻게 해야할지 모르겠습니다
제가 아직 내공이 부족해서인지...구체적으로 어떻게 해야할지 모르겠습니다.
BitArray가 멤버로 가지고 있는 g_playerarray가 [] 연산자를 오버로딩하지 않아서 그렇습니다.. []연산자를 오버로딩 하시거나 Array 클래스에서 해당 인덱스의 원소를 접근할수 있는 메소드를 만들어주시면 됩니다.
오버로딩이라면...operator BitArray하나 더 만드라는 말씀이신가요..
그리고...Array클래스에 멤버함수를 더 하나 만들라는 말씀이신것같은데..
어떻게 해야할지...!!!!!예제 부탁드리겠습니다.
답변에 감사드립니다.
Re: 음..
이미 있지 않습니까?
문제는 다음 코드입니다.
지금 type parameter Datatype은 Player인데, int로부터 Player로의
변환이 정의되지 않아서 그렇습니다. 제가 보기에 이 for 문은 없어도 되지
않을까 합니다. 이것 때문에 Array 클래스의 type parameter는 int로부터
변환이 정의되어야 한다는 요구 조건이 생기는데, Array 클래스의 목적으로
볼 때 불필요한 조건이 아닐까 합니다. for 문을 없애고, 그 대신 new 연산자에서
호출하는 디폴트 생성자에 의한 초기화로 대신하면 되겠습니다. (즉 Player
클래스의 디폴트 생성자를 정의하면 됩니다.)
Re: 음..
어래.. 있었군요.. :oops:
-------------------------------------------------------------------------------
It's better to appear stupid and ask question than to be silent and remain stupid.
[code:1]Player 클래스의 디폴트 생성자를 정의하면 됩니다.[/
Player 클래스의 디폴트 생성자를 정의하면 됩니다.
Player 클래스 생성자를 하나 만들어서...어떻게 하라는 말씀이신지.. 제가 아직도 내공이 부족해서...!!! 답변에 감사드립니다.생성자를 만들어서 어떻게 하냐구요? 컴파일하면 됩니다. :D 사실
생성자를 만들어서 어떻게 하냐구요? 컴파일하면 됩니다. :D
사실 위에 말한 for 문만 없애면 Player의 디폴트 생성자는 없어도 됩니다.
하지만 Array의 원소인 Player들을 어떤 형태로든 초기화할 필요는 있겠지요.
제가 님의 가르침대로 잘하고 있는지 모르겠지만...일단은 ..for문
제가 님의 가르침대로 잘하고 있는지 모르겠지만...
일단은 ..for문을 지우고 memset( m_array, 0x00, sizeof( m_array ));
이렇게 하고 Player 클래스들을 생성해서.
Player::Player( )
{
m_life = m_money = 0, m_experience = 0, m_level = 0;
}
이런식으로 했습니다.
다음과 같은 에러가 떨어졌습니다.
에러 메시지가 전에 올렸던 것과 같군요.int -> Player
에러 메시지가 전에 올렸던 것과 같군요.
int -> Player의 변환이 필요한 코드가 있는지 살펴보세요.
그리고 memset은 왜 쓰신 거죠? 필요없을 뿐만 아니라 위험해 보이는군요.
템플릿 코드가 .cpp 파일에 들어있군요. 템플릿 코드는 헤더에 넣으셔야
템플릿 코드가 .cpp 파일에 들어있군요. 템플릿 코드는 헤더에 넣으셔야 합니다. Array.cpp 에 들어 있는 모든 내용을 Array.h 에 옮겨주세요.
(doldori 님이 지적하신 사항은 물론 해결하셔야 합니다.)
[code:1]template <typename Datatype
vc7.1로 간단하게 테스트를 해봤습니다. 간단하게 주석도..
Life rushes on, we are distracted
감사합니다.더 노력해서...이런질문은 안올리도록 하겠습니다.오늘
감사합니다.
더 노력해서...이런질문은 안올리도록 하겠습니다.
오늘 하루도 즐거운 하루되세요..
댓글 달기