C++: ошибка: недопустимые операнды типов «String*» и «const char [7]» для двоичного «operator+»

Я изучаю cpp и в своем последнем задании я переписываю класс std::string. Итак, вот схема моего кода: строковый класс:

   class String {
    public:
        String(const char* sInput) {
            string = const_cast<char*> (sInput);                
        }

        const String operator+(const char* str) {
            //snip
            print();
        }

        void print() {
            cout<<string;
        }

        int search(char* str) {

        }

    private:
        char* string;
        int len;
};

О, и я должен сказать, что пытался объявить метод как String* operator+(const char* str) и как const String& operator+(const char* str) без изменений. И вот как я его запускаю:

int main(int argc, char* argv[]) {
    String* testing = new String("Hello, "); //works
    testing->print();//works
    /*String* a = */testing+"World!";//Error here.
return 0;
}

Полная ошибка выглядит так:

foobar.cc:13: ошибка: недопустимые операнды типов «String*» и «const char [7]» для двоичного «operator+»

Я искал в Google и в книге, из которой я учусь, но безуспешно. любой с предложениями? (Я почти уверен, что делаю что-то глупое, вам придется меня простить, я изначально программист PHP) Может ли кто-нибудь указать мне, что мне не хватает?


person Leon Fedotov    schedule 22.08.2009    source источник


Ответы (2)


Вероятно, вы не захотите использовать указатель на свой класс String. Попробуйте этот код:

int main(int argc, char* argv[]) {
    String testing = String("Hello, "); //works
    testing.print();//works
    String a = testing+"World!";
    return 0;
}

При определении новых операторов для типов C++ вы, как правило, будете работать непосредственно с фактическим типом, а не с указателем на ваш тип. Объекты С++, размещенные, как указано выше (как String testing), размещаются в стеке (живут до конца «области» или функции), а не в куче (живут до конца вашей программы).

Если вы действительно хотите использовать указатели на свой тип, вы должны изменить последнюю строку следующим образом:

String *a = new String(*testing + "World!");

Однако, следуя примеру std::string, вы обычно не хотите использовать такой строковый класс.

person Greg Hewgill    schedule 22.08.2009
comment
Хорошая идея, но теперь, когда я это делаю: String testing = new String(Hello, ); Я получаю следующую (такую ​​же) ошибку: foobar.cc:11: ошибка: запрошено преобразование из «String *» в нескалярный тип «String» - person Leon Fedotov; 23.08.2009
comment
Обратите внимание, что в моем примере я удалил ключевое слово new из этой строки. Использование new выделяет что-то в куче и возвращает указатель на него; без new это вызов конструктора для объекта в стеке. - person Greg Hewgill; 23.08.2009
comment
Вы должны использовать String testing("Hello, "); вместо String testing = String("Hello, ");, что без необходимости создаст временный объект String и вызовет конструктор копирования. - person sepp2k; 23.08.2009
comment
@ sepp2k: в случае присвоения одного значения в контексте объявления переменной (T x = T(y)) компилятору разрешается считать это тем же, что и T x(y) без присвоения. - person Greg Hewgill; 23.08.2009
comment
Ну, по крайней мере, gcc не компилирует T x = T(y);, если конструктор копирования T является закрытым. - person sepp2k; 23.08.2009
comment
В стандарте есть требование, что даже если компилятор выполняет оптимизацию, он все равно должен гарантировать, что конструктор копирования доступен, а если нет, то программа недействительна и должна быть отклонена. Один из редких случаев, когда стандарт изо всех сил мешает вам делать что-то, что работает на моей машине :-) - person Steve Jessop; 23.08.2009

Ваш оператор+ определен для String и const* char, а не для String*. Вы должны разыменовать testing перед его добавлением, т.е.:

String a = (*testing) + "World";

Хотя в данном случае я не вижу смысла делать проверку указателя на первом месте.

Изменить: создание строки без указателей будет выглядеть так:

String testing = "Hello, ";

or

String testing("Hello, ");

(оба эквивалентны).

person sepp2k    schedule 22.08.2009
comment
Это сработало :), но теперь я пытаюсь не использовать обозначение указателя при построении, и я получаю ту же ошибку в строке построения: foobar.cc:11: ошибка: преобразование из «String *» в нескалярный тип «String». Я должен признать, что эти указатели могут сбить с толку новичка. - person Leon Fedotov; 23.08.2009