I was implementing a String and was giving the definition in .h file. The code in String.h is the following:
#include<list>
class String
{
public:
String();//Constructor
String(char * copy);//For converting CString to String
const char *c_str(const String ©);//For converting String to Cstring
String(list<char> ©);//Copying chars from list
//Safety members
~String();
String(const String ©);
void operator = (const String ©);
protected:
int length;
char *entries;
};
The error is mentioned in the subject. What is it that I am not following?
You are missing a std:: in front of list<char> :
String(std::list<char> ©);
Fixed several of your issues at once:
#include <list>
class String
{
public:
String();
String(const String &c);
String(const char * c);
String(std::list<char> c); // No idea why someone would have this constructor, but it was included in the original ...
~String();
String& operator = (const String &c);
const char *c_str();
private:
unsigned int length;
char* entries;
};
Related
class MyString:public string
{
public:
MyString(){ string();}
MyString(const char* name){
string(name);
}
MyString(const MyString& a){
*this = a;
}
MyString(const string& a):string(a){}
MyString operator()(int start,int end){
MyString ret(substr(start,end));
return ret;
}
};
when I write this, it shows that
‘const char* name’ previously declared here
10 | MyString(const char* name){
| ~~~~~~~~~~~~^~~~
and string(name);
|
what should I do?
just like words written above
If you really want to write your own string class based in the standard string class then the way to do it is to use composition not inheritance. Based on the code written above, something like this
class MyString
{
public:
MyString() {}
MyString(const char* name) : my_string(name) {}
MyString(const std::string& name) : my_string(name) {}
MyString operator()(int start, int end) const {
return my_string.substr(start, end);
}
private:
std::string my_string;
};
I'm new to c++.I made a simple program that name members of class based on your input.
But for some reason, compiler shows this error - 'str': is not a member of 'std::basic_string<char,std::char_traits<char>,std::allocator<char>>', I have trouble understanding what it means.
Please help me out
here is my code -
#include <iostream>
#include <string>
#include <vector>
class mystring
{
private:
std::string *str;
public:
//constructors
mystring();
mystring(const std::string &strthing);
~mystring();
//methods
void display() const;
};
mystring::mystring() //defalt constructor
:str(nullptr)
{}
mystring::mystring(const std::string& strthing) //copy constructor
:str(nullptr)
{
delete str;
str = new std::string;
strcpy(this->str, strthing.str);
std::cout << "overloaded\n";
}
mystring::~mystring() //destructor
{
delete [] str;
}
void mystring::display() const //display func
{
std::cout << *str;
}
int main()
{
mystring thing;
mystring object{ "samurai" };
object.display();
}
I think something is wrong with the strcpy() function in overloaded constructor.
Thanks
There is nothing wrong with strcpy, but with how you use it. std::strings can be copied with their operator=:
std::string a;
std::string b;
a = b; // copy b to a
strcpy on the other hand is for c-strings, which a std::string is not:
char* strcpy( char* dest, const char* src );
It is unclear why you have a member of type pointer to std::string. You should either use a std::string (no pointer), or if this is an exercise to write your own string class (not an easy one!) then you should probably store the data in an array of chars.
The error you get is about strthing.str. Here strthing is a std::string which has no str member. If that constructor is supposed to be a copy constructor it should take a const mystring& as parameter not a const std::string&.
This is just a typo.
mystring::mystring(const std::string& strthing)
Should be
mystring::mystring(const mystring& strthing)
You don't use strcpy to copy std::string objects. Here's your constructor rewritten correctly (it's not a copy constructor because it doesn't copy mystring objects)
mystring::mystring(const std::string& strthing) // constructor from std::string
: str(new std::string(strthing)) // allocate new string by copying from strthing
{
std::cout << "overloaded\n";
}
Because your class allocates memory (not sure why it does but it does) you do actually need to write a genuine copy constructor and assignment operator
mystring::mystring(const mystring& strthing) // copy constructor
mystring& mystring::operator=(const mystring& strthing) // assignment operator
But I'll leave that to you.
Ther is a C++ trap between C++ type std::string and C type 'char*'.
std::string can convert to char* using std::string.c_str().
And strcpy takes char* and char const * as parameters.
In moderen C++ practice, use std::string usually, std::string * is not recommended to use.
If you want to use strcpy with std::string, you have to do the conversion between char * and std::string. Below is a simple Example:
std::string dest;
std::string source = "Hello, World!";
char temp[40];
strcpy(temp, source.c_str());
dest = temp;
Just started learning C++ recently and I'm attempting to make my own string class from scratch. I'm currently working on concatenating strings by overloading += and + operators. After reading this article, basic-rules-of-operator-overloading, I have come up with the following implementation;
String & String::operator+=(const String &o)
{
char * newBuffer = new char[this->size() + o.size() - 1];
//copy over 'this' string to the new buffer
int index = 0;
while (this->at(index) != 0x0)
{
*(newBuffer + index) = this->at(index);
index++;
}
//copy over the param string into the buffer with the offset
//of the length of the string that's allready in the buffer
int secondIndex = 0;
while (o.at(secondIndex) != 0x0)
{
*(newBuffer + index + secondIndex) = o.at(secondIndex);
secondIndex++;
}
//include the trailing null
*(newBuffer + index + secondIndex) = 0x0;
//de-allocate the current string buffer and replace it with newBuffer
delete[] this->s;
this->s = newBuffer;
this->n = index + secondIndex;
return *this;
}
inline String operator+(String lhs, const String &rhs)
{
lhs += rhs;
return lhs;
}
However, the compiler will not recognise the + overload! It does work if I place the function in the main test file (where I am calling the method) but not if I place it in my String.cpp file where all my other methods are located.
Here is my String.h file if you need it;
#include <iostream>
class String
{
public:
String(const char * s);
String(const String &o);
int size() const;
char at(int i) const;
String &operator+=(const String &o);
private:
char * s;
int n;
//needs to be a friend function defined OUTSIDE of the class as when using
//ostream << String you do not have access to the ostream so they can't be
//member operators
friend std::ostream & operator<<(std::ostream &os, const String &o);
};
Thanks for any help!
(also, anything you think I can improve on in regards to my implementation would be graciously received)
Well everyone already explained, so it should be as simple as just adding the forward declaration to the end of your .h file like this:
#include <iostream>
class String
{
public:
String(const char * s);
String(const String &o);
int size() const;
char at(int i) const;
String &operator+=(const String &o);
private:
char * s;
int n;
//needs to be a friend function defined OUTSIDE of the class as when using
//ostream << String you do not have access to the ostream so they can't be
//member operators
friend std::ostream & operator<<(std::ostream &os, const String &o);
};
//forward declaration
String operator+(String lhs, const String &rhs);
The forward declaration just tells the compiler to look for a function with that signature. When it doesn't find it in your current .cpp file it looks up on the other .cpp files. I hope this helps!
I need help figuring out how to overload the array operator for a MyString class that I have to create. I already have everything else figured out, but the arrays are giving me trouble, for some reason.
Here is my header file:
#ifndef MYSTRING_H
#define MYSTRING_H
#include <iostream>
#include <cstring> // For string library functions
#include <cstdlib> // For exit() function
using namespace std;
// MyString class: An abstract data type for handling strings
class MyString
{
private:
char *str;
int len;
public:
// Default constructor.
MyString()
{
str = 0;
len = 0;
}
// Convert and copy constructors.
MyString(char *);
MyString(MyString &);
// Destructor.
~MyString()
{
if (len != 0)
delete [] str;
str = 0;
len = 0;
}
// Various member functions and operators.
int length() { return len; }
char *getValue() { return str; };
MyString operator+=(MyString &);
MyString operator+=(const char *);
MyString operator=(MyString &);
MyString operator=(const char *);
bool operator==(MyString &);
bool operator==(const char *);
bool operator!=(MyString &);
bool operator!=(const char *);
bool operator>(MyString &);
bool operator>(const char *);
bool operator<(MyString &);
bool operator<(const char *);
bool operator>=(MyString &);
bool operator>=(const char*);
bool operator<=(MyString &);
bool operator<=(const char *);
MyString operator [](MyString *);
// Overload insertion and extraction operators.
friend ostream &operator<<(ostream &, MyString &);
friend istream &operator>>(istream &, MyString &);
};
#endif
What would the body look like for MyString::operator []?
MyString MyString::operator [](MyString *)
{
... what goes here
}
The syntax for using the array operator with an object of the given class is:
MyString s("Test");
char c = s[0];
The argument to the function is an integral value.
Hence, the operator needs to be declared as:
// The non-const version allows you to change the
// content using the array operator.
char& operator [](size_t index);
// The nconst version allows you to just get the
// content using the array operator.
char operator [](size_t index) const;
MyString MyString::operator [](MyString *)
That's not how you should typically use a subscript operator.
What do you expect when you are using the [] operator? By the way you declared it, you are using a string pointer as argument, and receiving a string as return.
Usually, you pass an index type (commonly an unsigned-integer like size_t) and return the character at that position. If that's what you want, you should do something along these lines:
char& MyString::operator [](size_t position)
{
// some error handling
return str[position];
}
char MyString::operator [](size_t position) const { /* ... */ }
For overall guidelines on overloading operators, take a look at What are the basic rules and idioms for operator overloading?.
Also, I would point out that your destructor is a bit odd:
if (len != 0)
delete [] str;
str = 0;
len = 0;
Your indentation level suggests that you expect everything to happen inside the if statement, but only the first one will. That is not particularly dangerous in this case, because only the delete would suffice.
There is no problem in deleteing a null pointer, and str and len will be destroyed shortly after, so you don't have to bother resetting them.
I have a class defined:
#ifndef _STRINGCLASS_H
#define _STRINGCLASS_H
using namespace std;
#include <iostream>
#include <vector>
class String {
protected:
int length;
vector<string> buf;
public:
String();
String(const char* input);
String(char input);
String(int input);
String(const String& input);
String(char input, int input2);
String& operator=(const String& input);
};
#endif
and am trying to overload the assignment operator by such:
String& operator=(const String& input) {
buf = input.buf;
length = input.length;
return *this;
}
and I get the error code that buf is protected and length is protected. I'm not sure what I am missing. How can I properly overload the assignment operator with vectors and ints?
You do not need to provide any special member functions for your class, because the compiler synthesized ones will do the right thing in this case. The best option is to remove the assignment operator and copy constructor from your class definition.
class String
{
protected:
int length;
vector<string> buf;
public:
String();
String(const char* input);
String(char input);
String(int input);
String(char input, int input2);
};
You need to define the implementation as part of the class. You are missing the class specifier:
// vvvvvvvv
String& String::operator=(const String& input) {
buf = input.buf;
length = input.length;
return *this;
}
As written, you are defining a free operator overload (not bound to a class), and it's actually invalid to declare a free assignment operator overload anyway.
From the perspective of a free operator overload that isn't a member of String, buf and length are indeed inaccessible because they are private.