Hello again,
Sorry to bother but I guess my C++ book isn't very good since it
obviously contains errors so the program code doesn't work with g++.
However I don't understand what the problem is. Last time the problem
was that "using namespace std" apparently had a "link" class/object
defined already. Now I get:
error: no matching function for call to 'String::String(String)'
See if you can spot the error because I can't:
- - - - - - - - - - - - - - -
// memory-saving String class
// overloaded assignment and copy constructor
#include <iostream>
#include <cstring> //for strcpy(), etc.
using namespace std;
////////////////////////////////////////////////////////////////
class strCount //keep track of number
{ //of unique strings
private:
int count; //number of instances
char* str; //pointer to string
friend class String; //make ourselves available
//member functions are private
//--------------------------------------------------------------
strCount(char* s) //one-arg constructor
{
int length = strlen(s); //length of string argument
str = new char[length+1]; //get memory for string
strcpy(str, s); //copy argument to it
count=1; //start count at 1
}
//--------------------------------------------------------------
~strCount() //destructor
{ delete[] str; } //delete the string
};
////////////////////////////////////////////////////////////////
class String //String class
{
private:
strCount* psc; //pointer to strCount
public:
String() //no-arg constructor
{ psc = new strCount("NULL"); }
//--------------------------------------------------------------
String(char* s) //1-arg constructor
{ psc = new strCount(s); }
//--------------------------------------------------------------
String(String& S) //copy constructor
{
psc = S.psc;
(psc->count)++;
}
//--------------------------------------------------------------
~String() //destructor
{
if(psc->count==1) //if we are its last user,
delete psc; // delete our strCount
else // otherwise,
(psc->count)--; // decrement its count
}
//--------------------------------------------------------------
void display() //display the String
{
cout << psc->str; //print string
cout << " (addr=" << psc << ")"; //print address
}
//--------------------------------------------------------------
void operator = (String& S) //assign the string
{
if(psc->count==1) //if we are its last user,
delete psc; // delete our strCount
else // otherwise,
(psc->count)--; // decrement its count
psc = S.psc; //use argument's strCount
(psc->count)++; //increment its count
}
};
////////////////////////////////////////////////////////////////
int main()
{
String s3 = "When the fox preaches, look to your geese.";
cout << "\ns3="; s3.display(); //display s3
String s1; //define String
s1 = s3; //assign it another String
cout << "\ns1="; s1.display(); //display it
String s2(s3); //initialize with String
cout << "\ns2="; s2.display(); //display it
cout << endl;
return 0;
}
- - - - - - - - - - - - - - -
I didn't make the comments. I just copy/pasted the code so I don't want
to spend time on removing them as I also find it okay that they're there.
Best regards / Med venlig hilsen
Martin J�rgensen
--
---------------------------------------------------------------------------
Home of Martin J�rgensen - http://www.martinjoergensen.dk
|
|
0
|
|
|
|
Reply
|
unoder.spam (554)
|
5/6/2006 2:48:34 PM |
|
"Martin J�rgensen" <unoder.spam@spam.jay.net> wrote in message
news:4jpui3-2j1.ln1@news.tdc.dk
> Hello again,
>
> Sorry to bother but I guess my C++ book isn't very good since it
> obviously contains errors so the program code doesn't work with g++.
>
> However I don't understand what the problem is. Last time the problem
> was that "using namespace std" apparently had a "link" class/object
> defined already. Now I get:
>
> error: no matching function for call to 'String::String(String)'
>
> See if you can spot the error because I can't:
Change the String copy contructor to take a const reference rather than a
plain reference (copy constructors should always take const references).
--
John Carson
> - - - - - - - - - - - - - - -
> // memory-saving String class
> // overloaded assignment and copy constructor
> #include <iostream>
> #include <cstring> //for strcpy(), etc.
> using namespace std;
> ////////////////////////////////////////////////////////////////
> class strCount //keep track of number
> { //of unique strings
> private:
> int count; //number of instances
> char* str; //pointer to string
> friend class String; //make ourselves available
> //member functions are private
>
>
> //--------------------------------------------------------------
> strCount(char* s) //one-arg constructor
> {
> int length = strlen(s); //length of string argument
> str = new char[length+1]; //get memory for string
> strcpy(str, s); //copy argument to it
> count=1; //start count at 1
> }
> //--------------------------------------------------------------
> ~strCount() //destructor
> { delete[] str; } //delete the string
> };
> ////////////////////////////////////////////////////////////////
> class String //String class
> {
> private:
> strCount* psc; //pointer to strCount
> public:
> String() //no-arg constructor
> { psc = new strCount("NULL"); }
> //--------------------------------------------------------------
> String(char* s) //1-arg constructor
> { psc = new strCount(s); }
> //--------------------------------------------------------------
> String(String& S) //copy constructor
> {
> psc = S.psc;
> (psc->count)++;
> }
> //--------------------------------------------------------------
> ~String() //destructor
> {
> if(psc->count==1) //if we are its last user,
> delete psc; // delete our strCount
> else // otherwise,
> (psc->count)--; // decrement its count
> }
> //--------------------------------------------------------------
> void display() //display the String
> {
> cout << psc->str; //print string
> cout << " (addr=" << psc << ")"; //print address
> }
> //--------------------------------------------------------------
> void operator = (String& S) //assign the string
> {
> if(psc->count==1) //if we are its last user,
> delete psc; // delete our strCount
> else // otherwise,
> (psc->count)--; // decrement its count
> psc = S.psc; //use argument's strCount
> (psc->count)++; //increment its count
> }
> };
> ////////////////////////////////////////////////////////////////
> int main()
> {
> String s3 = "When the fox preaches, look to your geese.";
> cout << "\ns3="; s3.display(); //display s3
>
> String s1; //define String
> s1 = s3; //assign it another String
> cout << "\ns1="; s1.display(); //display it
>
> String s2(s3); //initialize with String
> cout << "\ns2="; s2.display(); //display it
> cout << endl;
> return 0;
> }
>
> - - - - - - - - - - - - - - -
>
> I didn't make the comments. I just copy/pasted the code so I don't
> want to spend time on removing them as I also find it okay that
> they're there.
>
> Best regards / Med venlig hilsen
> Martin J�rgensen
>
> --
> ---------------------------------------------------------------------------
> Home of Martin J�rgensen - http://www.martinjoergensen.dk
|
|
0
|
|
|
|
Reply
|
jcarson_n_o_sp_am_ (646)
|
5/6/2006 3:12:03 PM
|
|
Martin Jørgensen wrote:
> Hello again,
>
> Sorry to bother but I guess my C++ book isn't very good since it
> obviously contains errors so the program code doesn't work with g++.
>
> However I don't understand what the problem is. Last time the problem
> was that "using namespace std" apparently had a "link" class/object
> defined already. Now I get:
>
> error: no matching function for call to 'String::String(String)'
>
> See if you can spot the error because I can't:
Well, it would have be much easier to spot if you had included the line
number or better even marked the line that produced the error.
>
> - - - - - - - - - - - - - - -
> // memory-saving String class
> // overloaded assignment and copy constructor
> #include <iostream>
> #include <cstring> //for strcpy(), etc.
> using namespace std;
> ////////////////////////////////////////////////////////////////
> class strCount //keep track of number
> { //of unique strings
> private:
> int count; //number of instances
> char* str; //pointer to string
> friend class String; //make ourselves available
> //member functions are private
>
>
> //--------------------------------------------------------------
> strCount(char* s) //one-arg constructor
> {
> int length = strlen(s); //length of string argument
> str = new char[length+1]; //get memory for string
> strcpy(str, s); //copy argument to it
> count=1; //start count at 1
> }
> //--------------------------------------------------------------
> ~strCount() //destructor
> { delete[] str; } //delete the string
> };
> ////////////////////////////////////////////////////////////////
> class String //String class
> {
> private:
> strCount* psc; //pointer to strCount
> public:
> String() //no-arg constructor
> { psc = new strCount("NULL"); }
> //--------------------------------------------------------------
> String(char* s) //1-arg constructor
> { psc = new strCount(s); }
> //--------------------------------------------------------------
> String(String& S) //copy constructor
Here is probably the problem. Your copy constructor claims to modify the
original string, because the parameter is a non-const reference. Try:
String(const String& S) //copy constructor
Since your whole program doesn't care about const-correctness, I guess
that's the point where your book is failing.
> {
> psc = S.psc;
> (psc->count)++;
> }
> //--------------------------------------------------------------
> ~String() //destructor
> {
> if(psc->count==1) //if we are its last user,
> delete psc; // delete our strCount
> else // otherwise,
> (psc->count)--; // decrement its count
> }
> //--------------------------------------------------------------
> void display() //display the String
> {
> cout << psc->str; //print string
> cout << " (addr=" << psc << ")"; //print address
> }
> //--------------------------------------------------------------
> void operator = (String& S) //assign the string
> {
> if(psc->count==1) //if we are its last user,
> delete psc; // delete our strCount
> else // otherwise,
> (psc->count)--; // decrement its count
> psc = S.psc; //use argument's strCount
> (psc->count)++; //increment its count
> }
> };
> ////////////////////////////////////////////////////////////////
> int main()
> {
> String s3 = "When the fox preaches, look to your geese.";
> cout << "\ns3="; s3.display(); //display s3
>
> String s1; //define String
> s1 = s3; //assign it another String
> cout << "\ns1="; s1.display(); //display it
>
> String s2(s3); //initialize with String
> cout << "\ns2="; s2.display(); //display it
> cout << endl;
> return 0;
> }
>
> - - - - - - - - - - - - - - -
>
> I didn't make the comments. I just copy/pasted the code so I don't want
> to spend time on removing them as I also find it okay that they're there.
>
>
> Best regards / Med venlig hilsen
> Martin Jørgensen
>
|
|
0
|
|
|
|
Reply
|
ramagnus (3485)
|
5/6/2006 3:12:56 PM
|
|
Martin J�rgensen wrote:
> I guess my C++ book isn't very good since it obviously contains errors so
> the program code doesn't work with g++.
Get /Accelerated C++/ by Koenig and Moo, so you can skip over these
low-level issues and learn to write useful programs sooner. And read more
than 3 tutorials.
> However I don't understand what the problem is. Last time the problem was
> that "using namespace std" apparently had a "link" class/object defined
> already. Now I get:
And that's a reason not to use 'using namespace std'.
> error: no matching function for call to 'String::String(String)'
On what line? Next time comment such a line with // <-- error
> String(String& S) //copy constructor
Make that String(String const & S). Without the 'const', the compiler
automatically generates another copy constructor for you, with the signature
String(String const & S). Then on this line...
> String s2(s3); //initialize with String
....the compiler can't disambiguate the two calls, or something.
--
Phlip
http://c2.com/cgi/wiki?ZeekLand <-- NOT a blog!!!
|
|
0
|
|
|
|
Reply
|
phlipcpp (2479)
|
5/6/2006 3:18:41 PM
|
|
Phlip wrote:
>> String(String& S) //copy constructor
>
> Make that String(String const & S). Without the 'const', the compiler
> automatically generates another copy constructor for you, with the
> signature String(String const & S). Then on this line...
>
>> String s2(s3); //initialize with String
>
> ...the compiler can't disambiguate the two calls, or something.
Reviewing the other two posts, I now realize I was the closest to the
answer. Strike "or something".
When a compiler can't disambiguate two calls, it declares that it can't find
the simplest thing that it was looking for. For example:
void foo(short x);
void foo(long x);
foo(10); // <-- will report a missing foo(int)
So the simplest thing it can infer from String s2(s3) is
String::String(String). So the error message asks for that constructor,
instead of the canonical String::String(String const &).
(Despite String::String(String) is an impossible constructor, which is an
unrelated point. If you wrote a copy constructor without any &, then s3
would call that copy constructor to copy into the parameter argument. And
that would recursively call the same copy constructor forever.)
I win!
--
Phlip
http://c2.com/cgi/wiki?ZeekLand <-- NOT a blog!!!
|
|
0
|
|
|
|
Reply
|
phlipcpp (2479)
|
5/6/2006 3:42:13 PM
|
|
John Carson wrote:
> "Martin J�rgensen" <unoder.spam@spam.jay.net> wrote in message
> news:4jpui3-2j1.ln1@news.tdc.dk
>
>>Hello again,
>>
>>Sorry to bother but I guess my C++ book isn't very good since it
>>obviously contains errors so the program code doesn't work with g++.
>>
>>However I don't understand what the problem is. Last time the problem
>>was that "using namespace std" apparently had a "link" class/object
>>defined already. Now I get:
>>
>>error: no matching function for call to 'String::String(String)'
>>
>>See if you can spot the error because I can't:
>
>
> Change the String copy contructor to take a const reference rather than a
> plain reference (copy constructors should always take const references).
Thanks! Problem solved.
Best regards / Med venlig hilsen
Martin J�rgensen
--
---------------------------------------------------------------------------
Home of Martin J�rgensen - http://www.martinjoergensen.dk
|
|
0
|
|
|
|
Reply
|
unoder.spam (554)
|
5/6/2006 3:48:56 PM
|
|
|
5 Replies
31 Views
(page loaded in 1.206 seconds)
|