This question already has an answer here:
I have no clue what is causing this. I google and find many solutions but none seem to apply to me. At first I thought it was because I originally had operator+= defined before operator+, but even after switching, the errors still exist. What is this?
Here are all the errors:
CMakeFiles\ex6_1.dir/objects.a(mystring.cpp.obj): In function `ZN14stringexercise8mystringpLERKS0_':
/CLionProjects/ex6.1/mystring.cpp:108: undefined reference to `stringexercise::operator+(stringexercise::mystring const&, stringexercise::mystring const&)'
CMakeFiles\ex6_1.dir/objects.a(mystring.cpp.obj): In function `ZN14stringexercise8mystringpLEPKc':
/CLionProjects/ex6.1/mystring.cpp:126: undefined reference to `stringexercise::operator+(stringexercise::mystring const&, char const*)'
CMakeFiles\ex6_1.dir/objects.a(mystring.cpp.obj): In function `ZN14stringexercise8mystringpLEc':
/CLionProjects/ex6.1/mystring.cpp:72: undefined reference to `stringexercise::operator+(stringexercise::mystring const&, char const*)'
collect2.exe: error: ld returned 1 exit status
mingw32-make.exe[3]: *** [ex6_1.exe] Error 1
CMakeFiles\ex6_1.dir\build.make:99: recipe for target 'ex6_1.exe' failed
mingw32-make.exe[2]: *** [CMakeFiles/ex6_1.dir/all] Error 2
CMakeFiles\Makefile2:74: recipe for target 'CMakeFiles/ex6_1.dir/all' failed
mingw32-make.exe[1]: *** [CMakeFiles/ex6_1.dir/rule] Error 2
mingw32-make.exe: *** [ex6_1] Error 2
CMakeFiles\Makefile2:81: recipe for target 'CMakeFiles/ex6_1.dir/rule' failed
Makefile:117: recipe for target 'ex6_1' failed
Here is my mystring.h
/*
* mystring.h
*
*/
#ifndef MYSTRING_H
#define MYSTRING_H
#include <iostream>
#include <cstdlib> // to have size_t
namespace stringexercise {
class mystring {
public:
// constructors
mystring();
mystring(const char str[ ]);
mystring( const std::string str );
mystring(const mystring& source);
virtual ~mystring( );
// modifying member functions
mystring& operator+=(const mystring& addend);
mystring& operator+=(const char addend[ ]);
mystring& operator+=(const char addend);
mystring& operator=(const mystring& source);
const char& operator[ ](size_t position) const; // char at a distinct position
char& operator[ ](size_t position); // char at a distinct position
// constant member functions which do not change the state of the object
std::size_t length( ) const { return occupied; } // return number of characters
const char* c_str() const { return sequence; } // return text as a C-string
void swap(mystring&); // exchange of two strings
bool is_empty(){ return (occupied == 0); } // check if empty
// friends
friend std::ostream& operator <<(std::ostream& outs, const mystring& source);
friend bool operator==(const mystring& s1, const mystring& s2);
friend bool operator!=(const mystring& s1, const mystring& s2);
friend bool operator>=(const mystring& s1, const mystring& s2);
friend bool operator<=(const mystring& s1, const mystring& s2);
friend bool operator> (const mystring& s1, const mystring& s2);
friend bool operator< (const mystring& s1, const mystring& s2);
private:
size_t occupied; // current number of characters
size_t capacity; // maximum number of characters
char *sequence; // pointer to the beginning of the string array
};
// Prototype declarations of NON-MEMBER functions
// to be used in context with class mystring
mystring operator+(const mystring& s1, const mystring& s2);
mystring operator+(const mystring& s1, const char* s2 );
mystring operator+(const char* s1, const mystring& s2);
bool operator==(const mystring& s1, const mystring& s2);
bool operator!=(const mystring& s1, const mystring& s2);
bool operator>=(const mystring& s1, const mystring& s2);
bool operator<=(const mystring& s1, const mystring& s2);
bool operator> (const mystring& s1, const mystring& s2);
bool operator< (const mystring& s1, const mystring& s2);
std::ostream& operator<<(std::ostream& outs, const mystring& source);
std::istream& operator>>(std::istream& ins, mystring& target);
} /* end namespace stringexercise */
#endif
Here is my mystring.cpp
#include "mystring.h"
#include <cstring>
using namespace stringexercise;
//size_t occupied; // current number of characters
//size_t capacity; // maximum number of characters
//char *sequence; // pointer to the beginning of the string array
/*
* constructors
*/
mystring::mystring() {
occupied = 0;
capacity = 16;
sequence = nullptr;
}
mystring::mystring(const char str[]) {
occupied = strlen(str);
capacity = occupied * 2;
sequence = new char[capacity];
strcpy(sequence, str);
}
mystring::mystring(const std::string str) {
occupied = str.length();
capacity = occupied * 2;
sequence = new char[capacity];
strcpy(sequence, str.c_str());
}
mystring::mystring(const mystring &source) {
occupied = source.length();
capacity = source.capacity;
sequence = new char[capacity];
strcpy(sequence, source.sequence);
}
mystring::~mystring() {
occupied = 0;
capacity = 0;
delete[] sequence;
}
/*
* operators
*/
mystring operator+(const mystring& s1, const mystring& s2){
int s1l = s1.length();
int s2l = s2.length();
char buffer[(s1l+s2l)+1];
for(int i=0; i<s1l; i++){
buffer[i] = s1[i];
}
for(int i=0; i<s2l; i++){
buffer[i+s1l] = s2[i];
}
buffer[s1l+s2l] = '\0';
return mystring(buffer);
}
mystring operator+(const mystring& s1, const char* s2){
int s1l = s1.length();
int s2l = strlen(s2);
char buffer[(s1l+s2l)+1];
for(int i=0; i<s1l; i++){
buffer[i] = s1[i];
}
for(int i=0; i<s2l; i++){
buffer[i+s1l] = s2[i];
}
buffer[s1l+s2l] = '\0';
mystring ret(buffer);
return ret;
}
mystring operator+(const char* s1, const mystring& s2){
int s1l = strlen(s1);
int s2l = s2.length();
char buffer[(s1l+s2l)+1];
for(int i=0; i<s1l; i++){
buffer[i] = s1[i];
}
for(int i=0; i<s2l; i++){
buffer[i+s1l] = s2[i];
}
buffer[s1l+s2l] = '\0';
mystring ret(buffer);
return ret;
}
mystring& mystring::operator+=(const mystring &addend) {
if(occupied + addend.length() < capacity){
*this = *this + addend;
return *this;
}else{
throw "too long to append";
}
}
mystring& mystring::operator+=(const char *addend) {
if(occupied + strlen(addend) < capacity){
*this = *this + addend;
return *this;
}else{
throw "too long to append";
}
}
mystring& mystring::operator+=(const char addend) {
if(occupied + 1 < capacity){
*this = *this + &addend;
return *this;
}else{
throw "too long to append";
}
}
mystring& mystring::operator=(const mystring &source) {
if(this != &source){
delete[] sequence;
occupied = source.occupied;
capacity = source.capacity;
sequence = new char[capacity];
strcpy(sequence, source.sequence);
}
}
const char& mystring::operator[](size_t position) const {
if (position > occupied - 1 || position < 0){
throw "index out of range";
}
return sequence[position];
}
char& mystring::operator[](size_t position) {
if (position > occupied - 1 || position < 0){
throw "index out of range";
}
return sequence[position];
}
/*
* single
*/
//void mystring::swap(mystring &) {
//
//}
//
//
//
//
/*
* operators2
*/
//std::ostream &operator<<(std::ostream &outs, const mystring &source) {
// return <#initializer#>;
//}
//
//bool operator==(const mystring &s1, const mystring &s2) {
// return false;
//}
//
//bool operator!=(const mystring &s1, const mystring &s2) {
// return false;
//}
//
//bool operator>=(const mystring &s1, const mystring &s2) {
// return false;
//}
//
//bool operator<=(const mystring &s1, const mystring &s2) {
// return false;
//}
//
//bool operator>(const mystring &s1, const mystring &s2) {
// return false;
//}
//
//bool operator<(const mystring &s1, const mystring &s2) {
// return false;
//}
Aucun commentaire:
Enregistrer un commentaire