First, here's a class definition and some associated functions inside a header names "phonemes.h"
It's very long so don't look at it all. Just the final "operator-" definition is causing the problem. I just posted the entire code just in case something in there that I'd overlooked was causing the problem.
Code:
#ifndef _PHONEMES_H__INCLUDED_
#define _PHONEMES_H__INCLUDED_
#include "main_header.h"
struct core_features{
UINT cons :1; //consonantal
UINT syll :1; //syllabic
UINT son :1; //sonorant
UINT lab :1; //labial
UINT cor :1; //coronal
UINT back :1; //back
};
struct secondary_features
{
UINT ant :1; //anterior
UINT dist :1; //distributed
UINT high :1; //high
UINT low :1; //low
UINT voice :1; //voiced
UINT spread :1; //spread glottis
UINT constr :1; //constricted glottis
UINT cont :1; //continuant
UINT del_rel :1; //delayed release
UINT lat :1; //lateral
UINT nas :1; //nasal
UINT atr :1; //advanced tongue root
};
struct ternary_features
{
UINT spread :1;
UINT atr :1;
};
class Phoneme{
protected:
core_features c_feat;
secondary_features s_feat;
UCHAR uc_c_feat;
WCHAR wc_s_feat;
public:
Phoneme(){*(PUCHAR)(&c_feat) = 0; *(PWCHAR)(&s_feat) = 0; uc_c_feat = 0; wc_s_feat = 0;}
~Phoneme(){}
void set_cons(int i = 1){c_feat.cons = i; UCHAR k = 1; i ? uc_c_feat |= (1 << 5) : ((k <<=5) & uc_c_feat ? uc_c_feat ^= k : 0);}
void set_syll(int i = 1){c_feat.syll = i; UCHAR k = 1; i ? uc_c_feat |= (1 << 4) : ((k <<=4) & uc_c_feat ? uc_c_feat ^= k : 0);}
void set_son(int i = 1){c_feat.son = i; UCHAR k = 1; i ? uc_c_feat |= (1 << 3) : ((k <<=3) & uc_c_feat ? uc_c_feat ^= k : 0);}
void set_lab(int i = 1){c_feat.lab = i; UCHAR k = 1; i ? uc_c_feat |= (1 << 2) : ((k <<=2) & uc_c_feat ? uc_c_feat ^= k : 0);}
void set_cor(int i = 1){c_feat.cor = i; UCHAR k = 1; i ? uc_c_feat |= (1 << 1) : ((k <<=1) & uc_c_feat ? uc_c_feat ^= k : 0);}
void set_back(int i = 1){c_feat.back = i; UCHAR k = 1; i ? uc_c_feat |= 1 : (k & uc_c_feat ? uc_c_feat ^= k : 0);}
void set_ant(int i = 1){s_feat.ant = i; WCHAR k = 1; i ? wc_s_feat |= (1 << 11) : ((k <<= 11) & wc_s_feat ? wc_s_feat ^= k : 0);}
void set_dist(int i = 1){s_feat.dist = i; WCHAR k = 1; i ? wc_s_feat |= (1 << 10) : ((k <<= 10) & wc_s_feat ? wc_s_feat ^= k : 0);}
void set_high(int i = 1){s_feat.high = i; WCHAR k = 1; i ? wc_s_feat |= (1 << 9) : ((k <<= 9) & wc_s_feat ? wc_s_feat ^= k : 0);}
void set_low(int i = 1){s_feat.low = i; WCHAR k = 1; i ? wc_s_feat |= (1 << 8) : ((k <<= 8) & wc_s_feat ? wc_s_feat ^= k : 0);}
void set_voice(int i = 1){s_feat.voice = i; WCHAR k = 1; i ? wc_s_feat |= (1 << 7) : ((k <<= 7) & wc_s_feat ? wc_s_feat ^= k : 0);}
void set_spread(int i = 1){s_feat.spread = i; WCHAR k = 1; i ? wc_s_feat |= (1 << 6) : ((k <<= 6) & wc_s_feat ? wc_s_feat ^= k : 0);}
void set_constr(int i = 1){s_feat.constr = i; WCHAR k = 1; i ? wc_s_feat |= (1 << 5) : ((k <<= 5) & wc_s_feat ? wc_s_feat ^= k : 0);}
void set_cont(int i = 1){s_feat.cont = i; WCHAR k = 1; i ? wc_s_feat |= (1 << 4) : ((k <<= 4) & wc_s_feat ? wc_s_feat ^= k : 0);}
void set_del_rel(int i = 1){s_feat.del_rel = i; WCHAR k = 1; i ? wc_s_feat |= (1 << 3) : ((k <<= 3) & wc_s_feat ? wc_s_feat ^= k : 0);}
void set_lat(int i = 1){s_feat.lat = i; WCHAR k = 1; i ? wc_s_feat |= (1 << 2) : ((k <<= 2) & wc_s_feat ? wc_s_feat ^= k : 0);}
void set_nas(int i = 1){s_feat.nas = i; WCHAR k = 1; i ? wc_s_feat |= (1 << 1) : ((k <<= 1) & wc_s_feat ? wc_s_feat ^= k : 0);}
void set_atr(int i = 1){s_feat.atr = i; WCHAR k = 1; i ? wc_s_feat |= 1 : (k & wc_s_feat ? wc_s_feat ^= k : 0);}
core_features* p_c_feat(){return &c_feat;}
secondary_features* p_s_feat(){return &s_feat;}
UCHAR uc_c_feat_value(){return uc_c_feat;}
WCHAR wc_s_feat_value(){return wc_s_feat;}
virtual void initialize(){*(PUCHAR)(&c_feat) = 0; *(PWCHAR)(&s_feat) = 0;}
//friend operator-(Phoneme&, Phoneme&);
};
class Vowel : public Phoneme
{
public:
Vowel()
{
*(PUCHAR)(&c_feat) = 0;
*(PWCHAR)(&s_feat) = 0;
this->set_son();
this->set_syll();
this->set_cont();
this->set_voice();
}
~Vowel(){}
virtual void initialize()
{
*(PUCHAR)(&c_feat) = 0;
*(PWCHAR)(&s_feat) = 0;
this->set_son();
this->set_syll();
this->set_cont();
this->set_voice();
}
};
class Consonant : public Phoneme
{
public:
Consonant()
{
*(PUCHAR)(&c_feat) = 0;
*(PWCHAR)(&s_feat) = 0;
this->set_cons();
}
~Consonant(){}
virtual void initialize()
{
*(PUCHAR)(&c_feat) = 0;
*(PWCHAR)(&s_feat) = 0;
this->set_cons();
}
};
inline int bit_diff(UINT i, UINT j)
{
i ^= j;
int result = 0;
for(; i > 0; i >>= 1)
i & 1 ? result++ : 0;
return result;
}
template<class T>
inline int bit_diff_t(T i, T j)
{
i ^= j;
T result = 0;
for(; i > 0; i >>= 1)
i & 1 ? result++ : 0;
return result;
}
//Commenting out this function gets rid of the problem.
int operator-(Phoneme& p1, Phoneme& p2)
{
//return 10 * bit_diff(*((PUINT) p1.p_c_feat()), *((PUINT) p2.p_c_feat())) + bit_diff(*((PUINT) p1.p_s_feat()), *((PUINT) p2.p_s_feat()));
return 10 * bit_diff_t<UCHAR>(p1.uc_c_feat_value(), p2.uc_c_feat_value()) + bit_diff_t<WCHAR>(p1.wc_s_feat_value(), p2.wc_s_feat_value());
}
#endif
The error message I get when I compile is as follows:
Code:
OT_OK error LNK2005: "int __cdecl operator-(class Phoneme &,class Phoneme &)" (??G@YAHAAVPhoneme@@0@Z) already defined in main.obj
OT_OK fatal error LNK1169: one or more multiply defined symbols found
The strange thing is, when I move that "operator-" function out of the header and into the cpp file containing the main routine, it compiles just fine.
What am I doing wrong?