Thread: Base class undefined

  1. #1
    Registered User
    Join Date
    Jul 2007
    Posts
    109

    Base class undefined

    I keep getting this error when I try to create a new class called ReverseString that is derived from the base class String. The error is:

    error C2504: 'String' : base class undefined

    I have to create this class so there is no way around it. I can't make a function in string that does what ReverseString is supposed to do. I have to figure out why this error message is occurring. Any help is greatly appreciated. I will post my header and source code for Reverse String and then in the following post I will add my string.h and string.cpp. Thanks.

    Code:
    //reverse.h
    
    #ifndef ReverseString_H
    #define ReverseString_H
    
    #include <iostream>
    #include "string.h"
    #include "strdrv.h"
    
    
    
    using namespace std;
    
    class ReverseString: public String
    {
    public:
    	ReverseString();
    	ReverseString(const ReverseString &rhs);
    	ReverseString(const char *str);
    	ReverseString operator=(const ReverseString &rhs);
    	ReverseString operator~();
    };
    
    #endif
    
    // reverse.cpp
    #define _CRT_SECURE_NO_DEPRECATE 1	
    #include <iostream>
    #include <assert.h>
    #include "reverse.h"
    
    
    using namespace std;
    
    ReverseString::ReverseString()
    {
    	name = NULL;
    	stringlength = 0;
    	size = stringlength + 1;
    	buf = new char [size];
    	memset(buf, 0 , size);
    	assert(buf != 0);
    	buf[0] = '\0';
    }
    
    ReverseString::ReverseString(const ReverseString &rhs)
    {
    	name = NULL;
    	stringlength = rhs.stringlength;
    	size = stringlength + 1;
    	buf = new char[size];
    	memset(buf, 0, size);
    	assert(buf != 0);
    	for(int i = 0; i <= stringlength; i++)
    		buf[i] = rhs.buf[i];
    }
    
    
    ReverseString::ReverseString(const char *str)
    {
    	name = NULL;
    	assert(str != 0);
    	stringlength = strlen(str);
    	size = stringlength + 1;
    	buf = new char[size];
    	memset(buf, 0 , size);
    	strcpy(buf, str);
    }
    
    ReverseString ReverseString::operator =(const ReverseString &rhs)
    {
    	if(this != &rhs)
    	{
    		delete []buf;
    		stringlength = rhs.stringlength;
    		size = stringlength + 1;
    		buf = new char[size];
    		memset(buf, 0, size);
    		strcpy(buf, rhs.buf);
    	}
    	return *this;
    }
    
    ReverseString ReverseString::operator ~()
    {
    	int k = 0;
    	for(int i = stringlength; i>=0; i--)
    	{
    		buf[i]= buf[k];
    		k++;
    	}
    	return buf;
    }
    Also here is the header for the driver program:

    Code:
    // strdrv.h
    
     
    
    #ifndef _STRDRV_H
    
    #define _STRDRV_H
    
     
    
    #include "string.h"
    
    #include "reverse.h"
    
    
     
    
    int main();
    
    void test1();
    
    void test2();
    
    void test3();
    
    void test4();
    
    void test5();
    
    void test6();
    
    void test7();
    
    void test8();
    
    void test9();
    
    void test10();
    
    void test11();
    
    void test12();
    
    void test13();
    
    void test14();
    
    void test15();
    
    void test16();
    
    void test17();
    
    void test18();
    
    void test19();
    
    void test20();
    
    void wait();
    
     
    
    #endif

  2. #2
    Registered User
    Join Date
    Jul 2007
    Posts
    109
    Here is the string header and source code:

    Code:
    //string.h
    
    #ifndef String_H
    #define String_H
    
    #include <iostream>
    #include "strdrv.h"
    
    
    using namespace std;
    
    
    class String
    {
    	
    	friend String operator+(const String& lhs, const String& rhs);
    	friend String operator+(const String& rhs, const char* str);
    	friend String operator+(const char* str, const String& rhs);
    	friend String operator+(const String& rhs, char str);
    	friend String operator+(char str, const String& rhs);
    	friend int operator==(const String& lhs, const String& rhs);
    	friend int operator!=(const String& lhs, const String& rhs);
    	friend int operator< (const String& lhs, const String& rhs);
    	friend int operator<=(const String& lhs, const String& rhs);
    	friend int operator> (const String& lhs, const String& rhs);
    	friend int operator>=(const String& lhs, const String& rhs);
    	friend char* operator+(const String &rhs, int element);
    	friend char* operator+(int element, const String &rhs);
    	friend ostream& operator<<(ostream&, const String&);
    
    public:
    	String();
    	String(const char* str);
    	String(char nme);
    	String(int sizeofstring);
    	String(const String &rhs);
    	String(char letter, int repeat);
    	~String();
    	void setName(const char* aname);
    	String& operator= (const String &rhs);
    	String& operator= (const char *st);
    	String& operator= (const char st);
    	String& operator+=(const String & str);
    	String operator+() const;
    	char& operator[](int i);
    	char& operator[](int i) const;
    	String& operator++();
    	String& operator--();
    	String operator++(int x);
    	String operator--(int x);
    	int getLength()const;
    	String substr(int start, int length);
    	const char* c_str() const;
    	void print();
    
    	
    	
    
    protected:
    	int stringlength;
    	int size;
    	char * name;
    	char *buf;
    	
    
    };
    
    #endif 
    
    // string.cpp
    #define _CRT_SECURE_NO_DEPRECATE 1
    #pragma warning(disable: 4996)
    #pragma warning(disable: 4267)
    #include <iostream>
    #include <cctype>
    #include <algorithm>
    #include <assert.h>
    #include "string.h"
    
    using namespace std;
    
    String::String()
    {
    	name = NULL;
    	stringlength = 0;
    	size = stringlength + 1;
    	buf = new char[size];
    	memset(buf, 0, size);
    }
    
    String::String(const char *str)
    { 
    	name = NULL;
    	assert( str != 0);
    	stringlength = strlen(str);
    	size = stringlength + 1;
    	buf = new char[size];
    	strcpy(buf, str);
    }
    
    String::String(char nme)
    {
    	name = NULL;
    	stringlength = 1;
    	size = stringlength + 1;
    	buf = new char[size];
    	memset(buf, 0, size);
    	buf[0] = nme;
    }
    
    String::String(int sizeofstring)
    {
    	name = NULL;
    	assert(sizeofstring >= 0);
    	stringlength = sizeofstring;
    	size = stringlength + 1;
    	buf = new char[size];
    	memset(buf, 0, size);
    }
    
    String::String(char letter, int repeat) : name(0), stringlength(repeat)
    {
    	buf = new char[repeat+1];
        memset( buf, 0, repeat + 1);
    	for(int i= 0; i< repeat; i++)
    		buf[i] = letter;
    }
    
    String::String(const String &rhs)
    {
    	name = NULL;
    	stringlength = rhs.stringlength;
    	size = stringlength + 1;
    	buf = new char[size];
    	strcpy(buf, rhs.buf);
    }
    
    String::~String()
    {
    	name = NULL;
    	delete []buf;
    
    }
    
    void String::setName(const char* aname)	
    {
    	name = NULL;
    	name = new char[strlen(aname + 1)];		
    	strcpy(name, aname);					
    }
    
    String& String::operator =(const String &rhs)
    {
    	if(this != &rhs)
    	{
    		delete []buf;
    		stringlength = rhs.stringlength;
    		size = stringlength + 1;
    		buf = new char[size];
    		strcpy(buf, rhs.buf);
    	}
    	return *this;
    }
    
    String& String::operator =(const char *st)
    {
    	String temp(st);
    	return operator =(temp);
    }
    
    String& String::operator =(char st)
    {
    	stringlength = 1;
    	size = stringlength + 1;
    	buf = new char[size];
    	memset(buf, 0 , size);
    	buf[0] = st;
    	return *this;
    }
    
    char& String::operator [](int i) const 
    {
    	static char sink = '\0';
    	if(i < 0 || i> stringlength)
    	{
    		cout<< "Error with element" << endl;
    		sink = '\0';
    		return sink;
    	}
    	else
    		return buf[i];
    }
    
    char& String::operator [](int i)
    {
    	static char sink = '\0';
    	if(i < 0 || i>stringlength)
    	{
    		cout<< "Error with element" << endl;
    		sink = '\0';
    		return sink;
    	}
    	else
    		return buf[i];
    }
    
    
    char* operator +(const String &rhs , int element)
    {
    	static char* blank = '\0';
    	if(element < 0 || element > rhs.getLength())
    		return blank;
    	else
    	{
    		char *buf = new char[rhs.getLength() + 1];
    		strcpy(buf, rhs.buf);
    		return &buf[element];
    	}
    }
    
    
    char* operator +(int element, const String &rhs)
    {
    	static char* blank = '\0';
    	if(element < 0 || element > rhs.getLength())
    		return blank;
    	else
    	{
    		char *buf = new char[rhs.getLength() + 1];
    		strcpy(buf, rhs.buf);
    		return &buf[element];
    	}
    }
    
    
    
    String& String::operator +=(const String & str)
    {
    	int newsize = getLength() + str.getLength();
    	stringlength = newsize;
    	size = stringlength + 1;
    	char *temp = new char[size];
    	memset(temp, 0, size);
    	strcpy(temp, buf);
    	strcat(temp, str.buf);
    	delete []buf;
    	buf = temp;
    	return *this;
    }
    
    int String::getLength()const
    {
    	return stringlength;
    }
    
    
    String operator +(const String& lhs, const String& rhs)
    {
    	String result(lhs);
    	result += rhs;
    	return result;
    }
    
    String operator +(char str, const String& rhs)
    {
    	String result(str);
    	result += rhs;
    	return result;
    }
    
    String operator +(const String& rhs, char str)
    {
    	String result(rhs);
    	result += str;
    	return result;
    }
    
    String operator +(const char* str, const String& rhs)
    {
    	String result(str);
    	result += rhs;
    	return result;
    }
    
    String operator +(const String& rhs, const char* str)
    {
    	String result(rhs);
    	result += str;
    	return result;
    }
    
    
    
    String String::substr(int start, int length)
    {
    	if(start <= 0 && start > stringlength)
    		cout<< "Start of substring not in string bounds" << endl;
    	else
    	{
    		if(length <= 0)
    			cout<< "Error: length of substring is negative" << endl;
    		else
    		{
    			if((start + length) > stringlength)
    				length = stringlength - start;
    			else
    			{
    				char* stringArray = new char[length + 1];
    				memset(stringArray, 0, length +1);
    				int i;
    				for(i = start; i < (start + length) ; i++)
    					stringArray[i-start] = (*this)[i];
    				stringArray[i - start] = '\0';
    				String temp(stringArray);
    				delete []stringArray;
    				return temp;
    			}
    		}
    	}
    }
    
    
    
    
    int operator==(const String& lhs, const String& rhs)
    {
    	return strcmp(lhs.buf, rhs.buf)==0;
    }
    
    int operator!= (const String& lhs, const String& rhs)
    {
    	return !(lhs.buf == rhs.buf);
    }
    
    int operator< (const String& lhs, const String& rhs)
    {
    	return strcmp(lhs.buf, rhs.buf) <0;
    }
    
    int operator<= (const String& lhs, const String&rhs)
    {
    	return strcmp(lhs.buf, rhs.buf) <=0;
    }
    
    int operator> (const String& lhs, const String& rhs)
    {
    	return strcmp(lhs.buf, rhs.buf) >0;
    }
    
    int operator>= (const String& lhs, const String& rhs)
    {
    	return strcmp(lhs.buf, rhs.buf) >=0;
    }
    
    ostream& operator<< (ostream& output, const String& stringoutput)
    {
    	output<< stringoutput.buf;
    	return output;
    }
    
    
    String& String::operator ++()
    {
    	for(int i = 0; i<stringlength; i++)
    		++buf[i];
    	return *this;
    
    }
    
    String String::operator +() const
    {
    	char *temp = new char[stringlength + 1];
    	strcpy(temp, buf);
    	std::transform(temp, temp+stringlength, temp, toupper );
    	return temp;
    }
    
    String String::operator ++(int x)
    {
    	String temp = *this;
    	++*this;
    	return temp;
    
    }
    
    String& String::operator --()
    {
    	for(int i = 0; i<stringlength; i++)
    		--buf[i];
    	return *this;
    }
    
    String String::operator --(int x)
    {
    	String temp = *this;
    	--*this;
    	return temp;
    }
    
    const char* String::c_str() const
    {
    	return buf;
    }
    
    void String::print()
    {
    	printf("%s: %s(%d)\n", name, buf, stringlength);
    }

  3. #3
    The larch
    Join Date
    May 2006
    Posts
    3,573
    I think the ReverseString class needs to know more about String than it is derived from it.

    Other than that, if I may say so, you seem to be going in the wrong direction (may-be because you have a very strange assignment). You already have a lot of operator overloads that are not intuitive and should be normal functions.

    What the reverse string has different is that it has one more unintuitive operator (~), but otherwise it is a pretty ordinary string. Therefore I don't see why you would even inherit it. Why can't String just implement it?
    I might be wrong.

    Thank you, anon. You sure know how to recognize different types of trees from quite a long way away.
    Quoted more than 1000 times (I hope).

  4. #4
    Registered User
    Join Date
    Jan 2005
    Posts
    7,366
    Try renaming string.h to a different filename (and also update the #includes that reference it). I guess it is possible that it is conflicting with the standard string.h header.

    Otherwise, I don't see why you would get that error. Is that the only compile error you get?


    Edit: Actually a more likely problem is the circular include you have. There's no reason to #include "string.h" and "reverse.h" inside strdrv.h.

  5. #5
    Registered User
    Join Date
    Sep 2001
    Posts
    752
    Are all of your files located in the same directory, and are you sure that is the working directory from which you are compiling?

    string.h is a standard library header, so you could possibly be picking up the wrong header with your #include directive.
    Callou collei we'll code the way
    Of prime numbers and pings!

  6. #6
    Registered User
    Join Date
    Jul 2007
    Posts
    109
    As soon as I take reverse.h out of strdrv.h then it hits me with these errors:

    error LNK2019: unresolved external symbol "void __cdecl test19(void)" (?test19@@YAXXZ) referenced in function _main

    fatal error LNK1120: 1 unresolved externals

  7. #7
    Registered User
    Join Date
    Jul 2007
    Posts
    109
    Here is the body of the driver:

    Code:
    // strdrv.cpp
    
     
    
    #include <iostream>
    
    #include <fstream>
    
    #include <stdlib.h>
    
    #include "strdrv.h"
    
    
    
     
    
    using namespace std;
    
     
    
    ofstream csis;
    
     
    
    
    int main() {
    
        csis.open("csis.dat");
    
        test1();
    
        test2();
    
        test3();
    
        test4();
    
        test5();
    
    	test6();
    
        test7();
    
        test8();
    
        test9();
    
    	test10();
    	
    	test11();
    
    	test12();
    	
        test13();
    
    	test14();
    
    	test15();
    
        test16();
    
        test17();
    
        test18();
    
    	test19();
    
    
        csis.close();
    
    }
    
     
    
    void test1() {
    
        system("cls");
    
        cout << "1. Testing: String default ctor." << endl << endl;
    
        csis << "1. Testing: String default ctor." << endl << endl;
    
        String s1;
    
        s1.setName("s1");
    
        s1.print();
    
        wait();
    
    }
    
     
    
    void test2() {
    
        system("cls");
    
        cout << "2. Testing: String one arg (char *) ctor." << endl << endl;
    
        csis << "2. Testing: String one arg (char *) ctor." << endl << endl;
    
        String s2("ABC");
    
        s2.setName("s2");
    
        s2.print();
    
        wait();
    
    }
    
     
    
    void test3() {
    
        system("cls");
    
        cout << "3. Testing: String one arg (char) ctor." << endl << endl;
    
        csis << "3. Testing: String one arg (char) ctor." << endl << endl;
    
        String s3('Z');
    
        s3.setName("s3");
    
        s3.print();
    
        wait();
    
    }
    
     
    
    void test4() {
    
        system("cls");
    
        cout << "4. Testing: String one arg (int) ctor." << endl << endl;
    
        csis << "4. Testing: String one arg (int) ctor." << endl << endl;
    
        String s4(10);
    
        s4.setName("s4");
    
        s4.print();
    
        wait();
    
    }
    
     
    
    void test5() {
    
        system("cls");
    
        cout << "5. Testing: String copy ctor." << endl << endl;
    
        csis << "5. Testing: String copy ctor." << endl << endl;
    
        String s5("Haley Laurel");
    
        s5.setName("s5");
    
        s5.print();
    
        String t5(s5);
    
        t5.setName("t5");
    
        t5.print();
    
        wait();
    
    }
    
     
    void test6() {
    
        system("cls");
    
        cout << "6. Testing: String two arg (char, int) ctor." << endl << endl;
    
        csis << "6. Testing: String two arg (char, int) ctor." << endl << endl;
    
        String s6('*', 10);
    
        s6.setName("s6");
    
        s6.print();
    
        wait();
    
    }
    
     
    
     
    
    void test7() {
    
        system("cls");
    
        cout << "7. Testing: String assignment." << endl << endl;
    
        csis << "7. Testing: String assignment." << endl << endl;
    
        String s7("Samantha Morgan"), t7, u7;
    
        s7.setName("s7");
    
        t7.setName("t7");
    
        u7.setName("u7");
    
        t7 = u7 = s7;
    
        s7.print();
    
        t7.print();
    
        u7.print();
    
        wait();
    
    }
    
     
    
    void test8() {
    
        system("cls");
    
        cout << "8. Testing: String assignment." << endl << endl;
    
        csis << "8. Testing: String assignment." << endl << endl;
    
        String s8("ABC");
    
        s8.setName("s8");
    
        s8 = s8;
    
        s8.print();
    
        wait();
    
    }
    
     
    
    void test9() {
    
        system("cls");
    
        cout << "9. Testing: Implicit type conversion." << endl << endl;
    
        csis << "9. Testing: Implicit type conversion." << endl << endl;
    
        String s9;
    
        s9 = "ABC";
    
        s9.setName("s9");
    
        s9.print();
    
        wait();
    
    }
    
     
    
    void test10() {
    
        system("cls");
    
        cout << "10. Testing: String concatenation." << endl << endl;
    
        csis << "10. Testing: String concatenation." << endl << endl;
    
        String s10("DEF");
    
        String t10('H');
    
          String u10("ABC" + s10 + "G" + t10 + 'I');
    
          u10.setName("u10");
    
        u10.print();
    
          String v10('X' + u10);
    
        v10.setName("v10");
    
        v10.print();
    
        wait();
    
    }
     
    
    void test11() {
    
        system("cls");
    
        cout << "11. Testing: String concatenation." << endl << endl;
    
        csis << "11. Testing: String concatenation." << endl << endl;
    
        String s11('A');
    
        String t11("BC");
    
        s11.setName("s11");
    
        t11.setName("t11");
    
        s11 += s11 += t11 += 'D';
    
        s11.print();
    
        t11.print();
    
        wait();
    
    }
    
     
    
    
     
    
    void test12() {
    
        system("cls");
    
        cout << "12. Testing: String unary operator." << endl << endl;
    
        csis << "12. Testing: String unary operator." << endl << endl;
    
        String s12("Unary +");
    
        String t12(+s12);
    
        s12.setName("s12");
    
        t12.setName("t12");
    
        s12.print();
    
        t12.print();
    
        s12 = +s12;
    
        s12.print();
    
        wait();
    
    }
     
    
    void test13() {
    
        system("cls");
    
        cout << "13. Testing: String comparison operators." << endl << endl;
    
        csis << "13. Testing: String comparison operators." << endl << endl;
    
        String s13("ABC"), t13("ABCD");
    
        s13.setName("s13");
    
        t13.setName("t13");
    
        s13.print();
    
        t13.print();
    
        cout << endl;
    
        cout << "== " << (s13 == t13 ? "True" : "False") << endl;
    
        cout << "!= " << (s13 != t13 ? "True" : "False") << endl;
    
        cout << "<  " << (s13 <  t13 ? "True" : "False") << endl;
    
        cout << "<= " << (s13 <= t13 ? "True" : "False") << endl;
    
        cout << ">  " << (s13 >  t13 ? "True" : "False") << endl;
    
        cout << ">= " << (s13 >= t13 ? "True" : "False") << endl;
    
        csis << endl;
    
        csis << "== " << (s13 == t13 ? "True" : "False") << endl;
    
        csis << "!= " << (s13 != t13 ? "True" : "False") << endl;
    
        csis << "<  " << (s13 <  t13 ? "True" : "False") << endl;
    
        csis << "<= " << (s13 <= t13 ? "True" : "False") << endl;
    
        csis << ">  " << (s13 >  t13 ? "True" : "False") << endl;
    
        csis << ">= " << (s13 >= t13 ? "True" : "False") << endl;
    
        wait();
    
    }
    
     
    
    void test14() {
    
        system("cls");
    
        cout << "14. Testing: Overloaded subscript operator." << endl << endl;
    
        csis << "14. Testing: Overloaded subscript operator." << endl << endl;
    
        String s14("C++ is fun.");
    
        s14.setName("s14");
    
        for (int i = -1; i <= s14.getLength(); i++) {
    
            char& ch = s14[i];
    
            if (ch != '\0')
    
                ++ch;
    
        }
    
        s14.print();
    
        wait();
    
    }
    
     
    
    void test15() {
    
        system("cls");
    
        cout << "15. Testing: Pointer notation." << endl << endl;
    
        csis << "15. Testing: Pointer notation." << endl << endl;
    
        String s15("ABCDE");
    
        s15.setName("s15");
    
        for(int i = 0; i < s15.getLength(); i++)
    
            ++(*(s15+i));
    
        for (int j = 0; j < s15.getLength(); j++) {
    
            cout << *(j + s15);
    
            csis << *(j + s15);
    
        }
    
        cout << endl;
    
        csis << endl;
    
        wait();
    
    }
    
     
     
    
    void test16() {
    
        system("cls");
    
        cout << "16. Testing: Increment and decrement operators." << endl << endl;
    
        csis << "16. Testing: Increment and decrement operators." << endl << endl;
    
        String s16("ABC");
    
        String t16(++s16);
    
        s16.setName("s16");
    
        t16.setName("t16");
    
        s16.print();
    
        t16.print();
    
       
    
        String u16("ABC");
    
        String v16(u16++);
    
        u16.setName("u16");
    
        v16.setName("v16");
    
        u16.print();
    
        v16.print();
    
     
    
        String w16("ABC");
    
        String x16(--w16);
    
        w16.setName("w16");
    
        x16.setName("x16");
    
        w16.print();
    
        x16.print();
    
     
    
        String y16("ABC");
    
        String z16(y16--);
    
        y16.setName("y16");
    
        z16.setName("z16");
    
        y16.print();
    
        z16.print();
    
        wait();
    
    }
    
     
    
    void test17() {
    
        system("cls");
    
        cout << "17. Testing: Substr function." << endl << endl;
    
        csis << "17. Testing: Substr function." << endl << endl;
    
        String s17("Jai Guru Dev"), t17;
    
        s17.setName("s17");
    
        t17.setName("t17");
    
        t17 = s17.substr(4, 8);
    
        s17.print();
    
        t17.print();
    
        wait();
    
    }
    
     
    
    void test18() {
    
        system("cls");
    
        cout << "18. Testing: Output function." << endl << endl;
    
        csis << "18. Testing: Output function." << endl << endl;
    
        String s18("Haley");
    
        String t18("Laurel");
    
        String u18("Stegman");
    
        cout << s18 << t18 << u18;
    
        cout << endl;
    
        csis << endl;
    
        wait();
    
    }
    
     
    
    
     
    
    void wait() {
    
        char buf;
    
     
    
        cout << endl << "Press any key to continue." << endl;
    
        csis << endl << endl;
    
        cin.get(buf);
    
    }

  8. #8
    The larch
    Join Date
    May 2006
    Posts
    3,573
    This should mean that you either don't have or fail to compile the implementation of test19.
    I might be wrong.

    Thank you, anon. You sure know how to recognize different types of trees from quite a long way away.
    Quoted more than 1000 times (I hope).

  9. #9
    Registered User
    Join Date
    Jul 2007
    Posts
    109
    I forgot to put test 19 in the driver. Sorry everybody

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 7
    Last Post: 11-17-2008, 01:00 PM
  2. Defining derivated class problem
    By mikahell in forum C++ Programming
    Replies: 9
    Last Post: 08-22-2007, 02:46 PM
  3. Base class initialization
    By VirtualAce in forum C++ Programming
    Replies: 4
    Last Post: 01-11-2004, 04:52 AM
  4. structure vs class
    By sana in forum C++ Programming
    Replies: 13
    Last Post: 12-02-2002, 07:18 AM
  5. Replies: 1
    Last Post: 11-27-2001, 01:07 PM