首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > C++ >

偶作的一个带有整数部分属性的字符串解决方法

2012-02-06 
偶作的一个带有整数部分属性的字符串编程时经常碰到像对学号,帐号的处理,用字符串无法实现自增或自减等功

偶作的一个带有整数部分属性的字符串
编程时经常碰到像对学号,帐号的处理,用字符串无法实现自增或自减等功能,感觉很不方便,便自己作了一个“带有整数部分性质的字符串”类(不知这样叫合不合适),本来想等通过了后把注释都写好了贴上来,让各位大侠帮忙提点意见。但现在出现点问题,编译通过了,但链接时出现了问题,报错:
正在编译...
test.cpp
IntString.cpp
Generating Code...
正在链接...
test.obj : error LNK2019: 无法解析的外部符号 "class std::basic_ostream<char,struct std::char_traits<char> > & __cdecl SLHnamespace::operator<<(class std::basic_ostream<char,struct std::char_traits<char> > &,class SLHnamespace::IntString<8> const &)" (??6SLHnamespace@@YAAAV?$basic_ostream@DU?$char_traits@D@std@@@std@@AAV12@ABV?$IntString@$07@0@@Z),该符号在函数 _main 中被引用
test.obj : error LNK2019: 无法解析的外部符号 "public: __thiscall SLHnamespace::IntString<8>::IntString<8>(char const *)" (??0?$IntString@$07@SLHnamespace@@QAE@PBD@Z),该符号在函数 _main 中被引用
I:\SourceCode\MySourceCode\MyProject\IntString带有整型部分属性的字符串\Debug\IntString带有整型部分属性的字符串.exe : fatal error LNK1120: 2 个无法解析的外部命令

编程时经常出现这种问题,到网上找也是众说纷纭,有人说是并发性问题,恳求各位大侠耐心帮忙解决一下,谢谢。

下边是代码:

//IntString.h

C/C++ code
 
#ifndef __INTSTRING_H__
#define __INTSTRING_H__

#include <string>
#include <iostream>
#include <cstring>
#include <vector>

using std::string;
using std::istream;
using std::ostream;
using std::vector;
using std::iterator;

namespace SLHnamespace
{
typedef unsigned int size_t;

class size_not_fit
{
public:
explicit size_not_fit() : _size( 0 ) {}
explicit size_not_fit( size_t si ) : _size( si ) {}
size_t size() const { return _size; }
private:
const size_t _size;
};

class out_of_rang
{
public:
explicit out_of_rang() : _index( 0 ) {}
explicit out_of_rang( size_t in ) : _index( in ) {}
size_t index() const { return _index; }
private:
const unsigned int _index;
};

class ref_on_empty
{
public:
explicit ref_on_empty() : _index( 0 ) {}
explicit ref_on_empty( unsigned int in ) : _index( in ) {}
unsigned int index() const { return _index; }
private:
const unsigned int _index;
};

template <size_t _size = 8>
class IntString
{
typedef unsigned int size_type;

friend istream & operator >>( istream & , IntString <_size> & ) throw( size_not_fit );
friend ostream & operator < <( ostream & , const IntString <_size> & ) throw( ref_on_empty );

friend bool operator ==( const string & , const IntString <_size> & ) throw();
friend bool operator ==( const char * , const IntString <_size> & ) throw();

friend bool operator !=( const string & , const IntString <_size> & ) throw();
friend bool operator !=( const char * , const IntString <_size> & ) throw();

friend bool operator >( const string & , const IntString <_size> & ) throw();
friend bool operator >( const char * , const IntString <_size> & ) throw();

friend bool operator <( const string & , const IntString <_size> & ) throw();
friend bool operator <( const char * , const IntString <_size> & ) throw();

friend bool operator >=( const string & , const IntString <_size> & ) throw();
friend bool operator >=( const char * , const IntString <_size> & ) throw();

friend bool operator <=( const string & , const IntString <_size> & ) throw();
friend bool operator <=( const char * , const IntString <_size> & ) throw();

friend IntString <_size> operator +( int , const IntString <_size> & ) throw();



public:
explicit IntString() throw() { _empty = true; }
explicit IntString( const char * ) throw( size_not_fit );
explicit IntString( const string & ) throw( size_not_fit );
explicit IntString( const IntString <_size> & ) throw() { str = _str.to_str();_empty = false; }

size_type size() const throw() { return _size; }
bool empty() const throw() { return _empty; }
const char * c_str() const throw() { return str.c_str(); }
const string& to_str() const throw() { return _size; }
void swap( IntString &is ) throw();

char& operator []( size_type _index ) const throw(){ return str[ _index ]; }
char& at( size_type _index ) const throw( out_of_rang , ref_on_empty );


IntString <_size> operator +( int i ) const throw();
IntString <_size> operator -( int i ) const throw();

IntString <_size>& operator =( const IntString & ) throw();
IntString <_size>& operator =( const string & ) throw();
IntString <_size>& operator =( const char * ) throw();

IntString <_size>& operator +=( int i ) throw();
IntString <_size>& operator -=( int i ) throw();
IntString <_size>& operator ++() throw();
IntString <_size> operator ++( int ) throw();

bool operator ==( const IntString <_size> & ) const throw();
bool operator ==( const string & ) const throw();
bool operator ==( const char * ) const throw();

bool operator !=( const IntString <_size> & ) const throw();
bool operator !=( const string & ) const throw();
bool operator !=( const char * ) const throw();

bool operator >( const IntString <_size> & ) const throw();
bool operator >( const string & ) const throw();
bool operator >( const char * ) const throw();

bool operator <( const IntString <_size> & ) const throw();
bool operator <( const string & ) const throw();
bool operator <( const char * ) const throw();

bool operator >=( const IntString <_size> & ) const throw();
bool operator >=( const string & ) const throw();
bool operator >=( const char * ) const throw();

bool operator <=( const IntString <_size> & ) const throw();
bool operator <=( const string & ) const throw();
bool operator <=( const char * ) const throw();

private:
string plus_to_other( size_type i ) const throw();
void plus_on_self( size_type i ) throw();
string minus_to_other( size_type i ) const throw();
void minus_on_self( size_type i ) throw();
string str;
bool _empty;
};
}
#endif



[解决办法]
帮顶,,
问一下,楼主用什么编译器??
[解决办法]
模版的实现要和定义放在同一个文件
[解决办法]
取消模版分离,看看还有没有其他问题
[解决办法]
要把IntString.cpp的内容拷贝到IntString.h里面去。
[解决办法]
1、没看出为什么需要用 _size 这个非类型模板参数
2、除了具有 no_throw guarantee 的部分函数(STL 要求析构函数和 swap 函数具有 no_throw guarantee)外,不要使用异常声明
3、out_of_rang 可以使用标准异常 std::out_of_range (#include <stdexcept>
4、operator ==, != 的语义错误。试试 IntString("1") == IntString("01")
------解决方案--------------------


模板编译模式的几种情况,还有更多的模板知识,参见http://www.devdiv.net/topic.asp?TOPIC_ID=314

Template 编译模式一:
Inclusion Model
// Max.h
template <typename Type>
Type Max(Type a, Type b);

template <typename Type>
Type Max(Type a, Type b)
{
return a > b ? a : b;
}

或者
//Max.cpp
template <typename Type>
Type Max(Type a, Type b)
{
return a > b ? a : b;
}
///////////////////////////////
// Max.h
template <typename Type>
Type Max(Type a, Type b);
#include “Max.cpp”
////
当然你也可以直接写出函数定义。
// Max.h
template <typename Type>
Type Max(Type a, Type b)
{
return a > b ? a : b;
}

实际上Inclusion Model就是将定义和实现全都放到头文件中,这对于template class的定义也是一样的,让我们前瞻一下template class

template <typename T>
class TryDef
{
public:
T getDefaultObject();
};

template<typename T>
T TryDef<T>::getDefaultObject()
{
return T();
}

恩~ 这个就是Inclusion Model,大多数情况我们就用这种模式。

Template 编译模式二:
Explicit Instantiation

这种模式隐含着C++一个语法。

template int Max(int a, int b);
看上面这行语句,这是定义了一个模版的实例,编译期间会根据这条语句直接生成一个int的Max函数,而不是通过使用者调用int版的Max函数在生成实例。

假如我们想要完成这样一个需求: 对于一个模版函数或类,我们只想生成我们指定的类型的版本,对于其他类型的版本一概不给出实现,如果用户调用就会出现连接错误。

这时候Explicit Instantiation 模式就派上用场了,我们这样组织源程序:
// Max.h
template <typename Type>
Type Max(Type a, Type b);

//Max.cpp

#include “Max.h”
template <typename Type>
Type Max(Type a, Type b)
{
return a > b ? a : b;
}

//MaxInst.cpp

#include “Max.cpp”

template float Max(float, float);

假如我们这样调用函数,
#include “Max.h”

Max(1, 2);
编译器会给出连接错误。
想让它编译通过的话需要加上int版本的Max函数,在MaxInst.cpp中加入:
template int Max(int,int);

还有一种编译模式常用的编译器都没有实现,叫做Separation Model,它利用export关键字,没法尝试所以偶就保持沉默了。

热点排行