简体   繁体   中英

Odd output from program when entering operator?

I'm probably missing something obvious here. This is my code (I'm just learning true C++, and I want to get some practice):

#include <iostream>
#include <cstring>

using namespace std;

class String {
private:
    char * value;
    int len;
    friend ostream & operator<<(ostream & os, String s);
public:
    String();
    String(const char * base);
    ~String();
    String operator+(String s);
    String operator*(int n);
    int length();
};

String::String() {
    this->value = new char[0];
    this->len = 0;
}

String::String(const char * base) {
    this->value = new char[this->len = strlen(base)];
    strcpy(this->value, base);
}

String::~String() {
    delete [] this->value;
}

int String::length() {
    return this->len;
}

String String::operator+(String s) {
    String n;
    delete [] n.value;

    cout << "Upon entering, I am: \"" << *this << "\"\n";

    n.value = new char[this->len + s.len];
    for(int i = 0; i < this->len; i++) {
        n.value[i] = this->value[i];
    }
    for(int i = 0; i < s.len; i++) {
        n.value[i + this->len] = s.value[i];
    }

    n.len = this->len + s.len;

    cout << "String::operator+(" << *this << ", " << s << ") succeeded with new value = \"" << n << "\"\n";

    return n;
}

String String::operator*(int n) {
    String s;
    delete [] s.value;

    s.value = new char[this->len * n];

    for(int i = 0; i < this->len * n; i++) {
        s.value[i] = this->value[i % this->len];
    }

    cout << "String::operator* succeeded with new value = \"" << s << "\"\n";

    return s;
}

ostream & operator<<(ostream & os, String s) {
    return os << s.value;
}

int main() {
    String s("Hello, world!");
    cout << s << "\nLength = " << s.length() << "\n\n";
    cout << (s + String("\n")) * 5;
    return 0;
}

And the string initializes and displays correctly, but my output is really strange; it seems that upon entering the operator+, "Hello, world?" suddenly becomes "x%r"?

C:\Users\Ryan\Documents\My Dropbox\C++ Projects>strings
Hello, world!
Length = 13

Upon entering, I am: "x%r"
String::operator+(x%r,
) succeeded with new value = "x%r"
String::operator* succeeded with new value = "╚%r"
─

Try this:

ostream & operator<<(ostream & os, const String& s) {
    return os << s.value;
}

otherwise your should define copy constructor for your String class.

You need to provide copy constructor and assignment operator.

There are a lot of problems with your code.

  1. You are managing your own memory. You should avoid doing this if at all possible.
  2. You are consitantly forgetting that strings have a null terminator. In order to accomodate the strin Hello, world! you need a char buffer that is 14 bytes, not 13.
  3. You have a len member variable that does effectively the same thing as the strlen function, except for the inconsistent consideration of #1 above.
  4. Your string class does not have a copy constructor, which results in wild pointers and eventually crashes.

Here is a refactoring of your code that pretty much works.

#define _CRT_SECURE_NO_WARNINGS

#include <iostream>
#include <cstring>

using namespace std;

class String {
private:
    char * value;
//    size_t len;
    friend ostream & operator<<(ostream & os, String s);
public:
    String();
    String(const char * base);
    String(const String& rhs) 
    {
        value = new char[strlen(rhs.value)+1];
        strcpy(value,rhs.value);
    }
    ~String();
    String operator+(String s);
    String operator*(int n);
    size_t length();
};

String::String() {
    this->value = new char[0];
}

String::String(const char * base) {
    this->value = new char[strlen(base)+1];
    strcpy(this->value, base);
}

String::~String() {
    delete [] this->value;
}

size_t String::length() {
    return strlen(value);
}

String String::operator+(String s) {
    String n;
    delete [] n.value;

    cout << "Upon entering, I am: \"" << *this << "\"\n";

    n.value = new char[strlen(value)+strlen(s.value)+1];
    for(int i = 0; i < strlen(value); i++) {
        n.value[i] = this->value[i];
    }
    for(int i = 0; i < strlen(s.value); i++) {
        n.value[i + strlen(value)] = s.value[i];
    }
    n.value[strlen(value)+strlen(s.value)] = '\0';

    cout << "String::operator+(" << *this << ", " << s << ") succeeded with new value = \"" << n << "\"\n";

    return n;
}

String String::operator*(int n) {
    String s;
    delete [] s.value;

    s.value = new char[(strlen(value)*n)+1];

    for(int i = 0; i < strlen(value) * n; i++) {
        s.value[i] = this->value[i % strlen(value)];
    }
    s.value[strlen(value)*n] = '\0';

    cout << "String::operator* succeeded with new value = \"" << s << "\"\n";

    return s;
}

ostream & operator<<(ostream & os, String s) {
    return os << s.value;
}

int main() {
    String s("Hello, world!");
    cout << s << "\nLength = " << s.length() << "\n\n";
    cout << (s + String("\n")) * 5;
    return 0;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM