First I would like to apologize for the quality of my code, I'm just learning. I have a university assignment.
String concatenation and adding one character to a string (like on the left and on the right). Implement using overloading the operator.
The question is this: I need to implement two overloads (operator ) First: adding one element to the end of the vector ( 'e', for example ). Second: adding an element to the beginning of the vector ('e' , for example).
I have problems in order to implement the second part of the assignment. I searched similar questions on stackoverflow, but they did not help me much.
Here is my code:
#include <iostream>
#include <vector>
using namespace std;
template <class T>
class String
{
private:
public:
vector<T> ptr_string;
String() // default value constructor (empty string)
{
ptr_string.push_back('\0');
}
String(const String& other) // copy constructor of the same type
{
int n = other.getLength();
for (int i = 0; i < n; i )
{
ptr_string.push_back(other.ptr_string[i]);
}
}
String(T symbol, int n) // n times repeated value constructor
{
for (int i = 0; i < n; i )
{
ptr_string.push_back(symbol);
}
}
String(String&& a) // move constructor
: ptr_string(a.ptr_string)
{
a.ptr_string = nullptr;
}
int getLength() const
{
return ptr_string.size();
}
void printString() const
{
int i = 0;
for (int i = 0; i < ptr_string.size(); i )
{
cout << ptr_string[i];
}
cout << endl;
}
template <typename T2>
auto operator (T2 b)
{
ptr_string.push_back(b);
return ptr_string;
}
auto operator (String const& a)
{
ptr_string.push_back(a);
return ptr_string;
}
};
int main()
{
String<char> P = String<char>('P', 10);
P 'e';
P.printString();
'e' P;
P.printString();
}
I tried to pass a reference to a vector as a parameter, but I ran into a problem that this is most likely not the right solution.
auto operator ( String const& a)
{
ptr_string.push_back(a);
return ptr_string;
}
String<char> P = String<char>( 'P', 10);
'e' P;
P.printString();
expected result: ePPPPPPPPPP
CodePudding user response:
First, operator
should not modify the current object. It should not return a vector but a new String<T>
. It should be const
.
Your char,int
constuctor misses to add a nullterminator. Maybe that was on purpose, but I changed it because I am using that constructor. Moreover, I removed the move constructor, because its not needed yet. In its implementation you assign nullptr
to the vector
which is wrong. You need not implement the move constructor, you can declare it as =default;
. This is what I also did for the copy constructor, because the compiler generated copy constructor is as good (or better) than your self written one.
Then, there is no
for 'e' String
in your code. When implmented as member then this
is always the left operand. You can implement it as free function.
#include <iostream>
#include <vector>
template<class T>
class String {
public:
std::vector<T> ptr_string;
String() { ptr_string.push_back('\0'); }
String(const String& other) = default;
String(T symbol, int n) {
for (int i = 0; i < n; i ) {
ptr_string.push_back(symbol);
}
ptr_string.push_back('\0');
}
int getLength() const {
return ptr_string.size();
}
void printString() const {
int i = 0;
for (int i = 0; i < ptr_string.size(); i ) {
std::cout << ptr_string[i];
}
std::cout << std::endl;
}
template<typename T2>
auto operator ( T2 b) const {
String res = *this;
res.ptr_string.push_back(b);
return res;
}
auto operator ( String const& a) {
String res = *this;
for (const auto& c : a.ptr_string) res.ptr_string.push_back(c);
return res;
}
};
template<typename T2,typename T>
auto operator (const T2& b,const String<T>& a) {
return String<T>(b,1) a;
}
int main() {
String<char> P = String<char>( 'P', 10);
auto Y = P 'e';
P.printString();
Y.printString();
auto Z = 'e' P;
P.printString();
Z.printString();
}
This is just minimum changes on your code. I would actually implement also the other operators outside of the class as free functions. The loop in the char,int
constructor should be replaced with the appropriate vector constructor and perhaps there is more which can be improved. For more on operator overloading I refer you to https://en.cppreference.com/w/cpp/language/operators and What are the basic rules and idioms for operator overloading?
CodePudding user response:
I don't think your assignment really cover a scenario that happens in real life. It is full of code smell. As @463035818_is_not_a_number mentionned operator usually don't modify the current object. But it is technically possible, See below. Vector are not meant to "push_front", avoid 'push_front' on vector as a general rule (here, i use deque for ex).
#include <deque>
#include <iostream>
#include <string>
template<class T>
struct ConcatenableDeq: std::deque<T>
{
void print() const
{
for (const auto& e: *this)
std::cout << e << " ";
std::cout << std::endl;
}
friend void operator (ConcatenableDeq<T>& cv, const T& v)
{
cv.push_back(v);
}
friend void operator (const T& v, ConcatenableDeq<T>& cv)
{
cv.push_front(v);
}
};
int main(int argc, char* argv[])
{
ConcatenableDeq<char> cv({ '1', '2', '3' });
cv.print();
cv '4';
cv.print();
'0' cv;
cv.print();
// output:
// 1 2 3
// 1 2 3 4
// 0 1 2 3 4
}