Thread: const object error

  1. #1
    Registered User
    Join Date
    Mar 2003
    Posts
    134

    const object error

    why am I getting this error: l-value specifies const object

    here is the code;-

    .h file
    Code:
    // String.h: interface for the String class.
    //
    //////////////////////////////////////////////////////////////////////
    
    #include<stdio.h>
    #include<iostream>
    using namespace std;
    
    #if !defined(AFX_STRING_H__B89E5B66_2BB2_467B_B470_66ED708714DC__INCLUDED_)
    #define AFX_STRING_H__B89E5B66_2BB2_467B_B470_66ED708714DC__INCLUDED_
    
    #if _MSC_VER > 1000
    #pragma once
    #endif // _MSC_VER > 1000
    
    
    
    
    class String  
    {
    public:
    	String(const char* = "");//done
    	String(const String&);//done
    	virtual ~String();//done
    	bool operator !()const;//done
    	char &operator[](const int)const;
    	
    	String operator +(const char*)const;//done
    	String operator +(const String &)const;//done
    	void operator = (const char*);//done
    	const char* getString() const;//done
    
    private:
    	char *stringPtr ;
    	int length;
    	void setString(const char*);
    
    
    };
    
    istream &operator >>(istream&, String&);
    ostream &operator <<(ostream&, const String&);
    
    class OutOfRange
    {
    public:
    	OutOfRange(int s, int p):size(s),position(p)
    	{
    	}
    
    	const char* getError()
    	{
    		static char error[200];
    
    		sprintf(error,"20th char in the string is Access attempt position %d on string of size %d\n",position, size);
    		
    		return error;
    	}
    
    private:
    	int size;
    	int position;
    };
    
    
    #endif // !defined(AFX_STRING_H__B89E5B66_2BB2_467B_B470_66ED708714DC__INCLUDED_)
    .cpp file
    Code:
    // String.cpp: implementation of the String class.
    //
    //////////////////////////////////////////////////////////////////////
    
    #include "String.h"
    #include<string.h>
    #include<assert.h>
    #include<iostream>
    using namespace std;
    
    
    //////////////////////////////////////////////////////////////////////
    // Construction/Destruction
    //////////////////////////////////////////////////////////////////////
    
    String::String(const char* s):length(strlen(s))
    {
    	setString(s);
    }
    
    void String::setString(const char *string1)
    {
    	stringPtr = new char[length + 1]; //length is of string1, the current obj
    	assert(stringPtr != 0);  //terminate if memory not allocated
    	strcpy(stringPtr, string1);
    }
    
    
    String::String(const String &other):length(other.length)
    {
    	setString(other.stringPtr);
    }
    
    const char* String::getString()const
    {
    	return stringPtr;
    }
    
    
    String::~String()
    {
    	delete[] stringPtr;
    
    }
    
    void String::operator =(const char* newString)
    {
    	if(stringPtr)
    		delete[] stringPtr;
    
    	if(stringPtr!='\0')
    	{
    		stringPtr= new char[strlen(newString)+1];
    		strcpy(stringPtr,newString);
    		length=strlen(newString);
    		
    	}
    
    }
    
    String String::operator +(const char *string2)const
    {
    	char* buffer = new char[strlen(string2) + length + 1];
    	strcat(strcpy(buffer,stringPtr),string2);
    	String temporary = buffer;
    	delete[] buffer;
    	return temporary;
    }
    
    String String::operator + (const String& object)const
    {
    	return operator +(object.stringPtr);
    
    }
    
    char& String::operator [](const int k)const
    {
    	if(k<0 || k>=length)throw OutOfRange(length,k);
    	else return stringPtr[k];
    
    
    }
    
    bool String::operator !()const
    {
    	return length==false;
    }
    
    istream& operator>>(istream& in, String& obj1)
    {
    	char buffer[80];
    	in >> buffer;
    	obj1 = buffer;   
    	return in;
    }
    ostream& operator<<(ostream& out, const String& obj2)
    {
    	out << obj2.getString();
    	return out;
    }
    main.cpp
    Code:
    #include <iostream>
    #include "String.h"
    using namespace std;
    
    void checkString(String obj)
    {
    	cout << "Given String is ";
    	if (!obj)
    		cout << "empty\n";
    	else
    		cout << " not empty\n";
    }
    
    void printString(const String& stringObj)
    {
    	cout << stringObj << endl;
    
    	try
    	{
    		cout << "First char in the string is " << stringObj[0] << endl;
    	}
    	catch(OutOfRange& exceptionObj)
    	{
    		cout << exceptionObj.getError() << endl;
    	}
    
    	try
    	{
    		cout << "20th char in the string is ";
    		cout << stringObj[19] << endl;
    	}
    	catch(OutOfRange& exceptionObj)
    	{
    		cout << exceptionObj.getError() << endl;
    	}
    }
    
    void main()
    {
    	const String hello = "Hello!";
    
    	String greet = hello + " there ";
    
    	printString(greet);
    
    	cout << "Now you may create your own string:\n";
    
    	String myString;
    
    	cin >> myString;
    
    	cout << "You entered:";
    	printString(myString);
    
    	String bigString = greet + myString;
    
    	printString(bigString);
    
    	try
    	{
    		greet[1] = 'i';
    	}
    	catch(OutOfRange& exceptionObj)
    	{
    		cout << exceptionObj.getError() << endl;
    	}
    
    	printString(greet);
    	checkString(greet);
    
    	String eString;
    	checkString(eString);
    }
    Last edited by noob2c; 07-26-2003 at 09:26 PM.

  2. #2
    Registered User
    Join Date
    May 2003
    Posts
    1,619
    You're seriously abusing const. You're making things const that you don't want to be constant at all.

    For example, your main problem:

    const char &operator [](const int);
    const char& operator[](int) const;

    1) Why are there 2 of them? You only need 1.
    2) It's not at all const correct. Firstly:

    * The return cannot be const because you want to be able to do things like s[0] = 'p';. If the return is const, then it can't modify the value.

    * It makes no sense to make the int const, because it's passed by copy so it couldn't modify the original if it tried.

    * The function itself shouldn't be const because it must return a non-const reference.

    There should be exactly one operator[], and it should be:

    char & operator[](int);

  3. #3
    Registered User
    Join Date
    Mar 2003
    Posts
    134
    doing that gives me this

    (26) : error C2678: binary '[' : no operator defined which takes a left-hand operand of type 'const class String' (or there is no acceptable conversion)

  4. #4
    Registered User
    Join Date
    Mar 2003
    Posts
    134
    fixed it, thanks alot for your suggestions

    but why is the output from the buffer in OutOfRange class say 20th character in the string twice before printing the rest, i edited the code, and it is the working one with this slight problem.
    Last edited by noob2c; 07-26-2003 at 09:27 PM.

  5. #5
    Guest Sebastiani's Avatar
    Join Date
    Aug 2001
    Location
    Waterloo, Texas
    Posts
    5,708
    Code:
    if(stringPtr)
    		delete[] stringPtr;
    
    	if(stringPtr!='\0')
    	{
    		stringPtr= new char[strlen(newString)+1];
    		strcpy(stringPtr,newString);
    		length=strlen(newString);
    		
    	}


    wrong. You want to check the pointer AFTER allocation, and anyway, afterward you should compare it to NULL, not '\0'.



    Code:
    if(stringPtr)
    		delete[] stringPtr;
    
     stringPtr= new char[strlen(newString)+1];
    
    	if(stringPtr!=NULL)
    	{
    		
    		strcpy(stringPtr,newString);
    		length=strlen(newString);
    		
    	}


    You forgot to delete your string here, and also forgot to change 'length' to strlen(string1):



    Code:
    void String::setString(const char *string1)
    {
    	stringPtr = new char[length + 1]; //length is of string1, the current obj
    	assert(stringPtr != 0);  //terminate if memory not allocated
    	strcpy(stringPtr, string1);
    }

    After you fix that, you need to call setString within
    void String:operator =(const char* newString), otherwise you're just duplicating code.



    Here, you return a temporary object. You can't do that because it's destructor will be called and also the OS might have already tromped over it anyway by that time.

    Code:
    String String:perator +(const char *string2)const
    {
    	char* buffer = new char[strlen(string2) + length + 1];
    	strcat(strcpy(buffer,stringPtr),string2);
    	String temporary = buffer;
    	delete[] buffer;
    	return temporary;
    }
    The easyest way to do it would be:

    Code:
    String String:operator +(const char *string2)const
    {
    	String temp(stringPtr);
    	strcat(temp.getString(), string2);
    	return String(temp);
    }

    That would allow the returned String to remain valid after leaving the function.
    Code:
    #include <cmath>
    #include <complex>
    bool euler_flip(bool value)
    {
        return std::pow
        (
            std::complex<float>(std::exp(1.0)), 
            std::complex<float>(0, 1) 
            * std::complex<float>(std::atan(1.0)
            *(1 << (value + 2)))
        ).real() < 0;
    }

  6. #6
    Registered User
    Join Date
    Mar 2003
    Posts
    134
    Hi I made this change, like u said check after allocation.

    Code:
    void String::operator =(const char* newString)//overloaded =
    {
    	if(stringPtr)            //if stringPtr exists
    		delete[] stringPtr;  //delete it
    	stringPtr= new char[strlen(newString)+1];
    	if(stringPtr!=NULL)      
    	
    		 {strcpy(stringPtr,newString);
    		 length=strlen(newString);}
    }
    but why delete stringPtr, it belongs to the new class created , and length is a member variable of the class holding the length of the new string creates.


    and the last change u suggested gives me some const error

    i cant edit the main.cpp, that has to be the same

  7. #7
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    There should be exactly one operator[], and it should be:
    Wrong. There should be exactly two operator[] per argument type, and they should be

    value_type &operator [](arg_type);
    const value_type &operator [](arg_type) const;
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Another syntax error
    By caldeira in forum C Programming
    Replies: 31
    Last Post: 09-05-2008, 01:01 AM
  2. Game Pointer Trouble?
    By Drahcir in forum C Programming
    Replies: 8
    Last Post: 02-04-2006, 02:53 AM
  3. load gif into program
    By willc0de4food in forum Windows Programming
    Replies: 14
    Last Post: 01-11-2006, 10:43 AM
  4. Please Help - Problem with Compilers
    By toonlover in forum C++ Programming
    Replies: 5
    Last Post: 07-23-2005, 10:03 AM
  5. ras.h errors
    By Trent_Easton in forum Windows Programming
    Replies: 8
    Last Post: 07-15-2005, 10:52 PM