I have implementation of String class as in Bjarne “C++…”. I want to have read() and other accessor functions inlined, so I marked them inline. It’s ok, but defining hash function that do a read on a reference to class String in main file gives error LNK2019 unresolved external symbol char __thiscall String::read(int)const
why is this unresolved?
class String in String.h:
#include <string.h>
class String{
struct Srep{ // representation
char* s; // pointer to elements
int sz; // number of characters
int n; // reference counter
Srep(int nsz, const char* p){
n=1;
sz=nsz;
s=new char[sz+1]; // add space for terminator
strcpy(s,p);
}
~Srep(){delete[]s;}
Srep* get_own_copy(){ // clone if necessary
if(n==1)return this;
n--;
return new Srep(sz,s);
}
void assign(int nsz, const char* p){
if(sz!=nsz){
delete[]s;
sz=nsz;
s=new char[sz+1];
}
strcpy(s,p);
}
private: //prevent copying
Srep(const Srep&);
Srep& operator=(const Srep&);
};
Srep* rep;
public:
class Cref{ // reference to char
friend class String;
String& s;
int i;
Cref(String& ss, int ii):s(ss), i(ii){}
public:
inline operator char(){ // yield value
return s.read(i);
}
inline void operator=(char c){ // change value
s.write(i,c);
}
};
class Range{};
String(); // x=""
String(const char*); // x="abnm'
String(const String&); // x=other_string
String& operator=(const char*);
String& operator=(const String&);
~String();
// access operators
void check(int i)const;
inline char read(int i)const;
void write(int i, char c);
Cref operator[](int i);
char operator[](int i)const;
int size()const;
};
String.cpp:
#include "stdafx.h"
#include "String.h"
String::String(){ // the empty string is the default value
rep=new Srep(0,"");
}
String::String(const String& x){ // copy constructor
x.rep->n++;
rep=x.rep; // share representation
}
String::~String(){
if(--rep->n==0)delete rep;
}
String& String::operator=(const String& x){ // copy assignment
x.rep->n++; // protects against "st=st"
if(--rep->n==0)delete rep;
rep=x.rep;
return *this;
}
// pseudo-copy operations taking const char* args are provided to allow
//string literals
String::String(const char* s){
rep=new Srep(strlen(s),s);
}
String& String::operator=(const char* s){
if(rep->n==1) // recycle Srep
rep->assign(strlen(s),s);
else{ //use new Srep
rep->n--;
rep=new Srep(strlen(s),s);
}
return *this;
}
// access operators
inline void String::check(int i)const{
if(i<0||rep->sz<=i)throw Range();
}
inline char String::read(int i)const{ // unchecked access to s
return rep->s[i];
}
inline void String::write(int i, char c){
rep=rep->get_own_copy();
rep->s[i]=c;
}
inline String::Cref String::operator[](int i){
check(i);
return Cref(*this,i);
}
inline char String::operator[](int i)const{// checked access to s
check(i);
return rep->s[i];
}
inline int String::size()const{
return rep->sz;
}
main file:
// Bjarne_exercise_string.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include "String.h"
int hash(const String& s){
//int h=s.read(0);
//const int max=s.size();
//for(int i=1;i<max;i++){
// h^=s.read(i)>>1; // unchecked access to s (1st take s[i], then rightshift, and then XOR h and this)
//}
//return h;
return 4;
}
int _tmain(int argc, _TCHAR* argv[])
{
String s1;
String s2;
String s3="s3";
String s4("s4");
String s5(s3);
s5=s4;
s3=s4;
//int i=hash(s3);
//i=hash(s1);
return 0;
}
To have function inlined it should be defined in header.
If you really want inline functions move definitions to header or move them to body of the class and remove inline.
To have mo linkage arrors remove inline specifier before
read