Создание пользовательского класса String, и у меня возникли проблемы с перегрузкой оператора ' <' для вывода. Я пробовал несколько разных способов его написания (прокомментировал код ниже, для справки и, поскольку они не работают), и получить различные ошибки. Для начала, Я получаю ошибку, используя код:Проблемы с перегрузкой Оператор «<<»
Ошибка 1: Ошибка C2804: бинарный «оператор < <» имеет слишком много параметров линии 53
Ошибка 2: ошибка C2333: «Строка оператор :: < < ': ошибка в объявлении функции; пропуская функцию: линия тела 53
Ошибка 3: ошибка C2679: двоичный '< <': оператор не найден, который принимает правый операнд типа «String» (или нет приемлемого преобразования), строка 180 (есть пучок из них)
Поскольку файл имеет более 300 строк, и я сомневаюсь, что вам, ребята, нужно все это прочитать, я его отпишу - некоторые из них, но если вы хотите 300 строк, я буду обязательно отредактируйте это.
Кроме того, я знаю, что «использование пространства имен std» в заголовке - это плохая практика. Извините, это старый файл, с которым я работаю, и я обещаю, что не буду включать его в будущие заголовочные файлы.
Тем не менее, вот код (и спасибо за помощь):
Как я уже сказал, спасибо за тонну до тех, кто читает и реагирует ниже. Я потратил около двух часов, пытаясь найти жизнеспособное решение, и сообщения, которые я искал, были слишком сложны для меня, чтобы понять или не применялись в моем случае. От взгляда на веб-сайт cplusplus я увидел, что функция оператора < < принимает только один параметр, однако у него возникли проблемы, связанные с этим. Если вы, ребята, опубликуете то, что, по вашему мнению, будет работать, я попробую и ответю.
Спасибо всем! Дайте мне знать, не хватает ли какой-либо важной информации.
#pragma once
#include <iostream>
#include <sstream>
using namespace std;
#define NOT_FOUND -1
//ostream& operator << (ostream& out, const String& myString);
// C++ String class that encapsulates an ASCII C-string
class String
{
public:
// Default constructor
String()
{
Text = NULL;
}
// MUST HAVE: Copy-constructor that performs deep copy
String(const String& source)
{
Text = NULL;
// Call the assignment operator to perform deep copy
*this = source;
}
// Init-constructor to initialize this String with a C-string
String(const char* text)
{
Text = NULL;
// Call the assignment operator to perform deep copy
*this = text;
}
// Init constructor, allocates this String to hold the size characters
String(int size)
{
Text = new char[size];
}
// Destructor
~String()
{
delete[] Text;
}
// This is what I would love to have work.
ostream& operator << (ostream& out, const String& myString)
{
return out << myString.GetText();
}
// Returns a new string that corresponds to a substring of this String
// beginning at startPosition and length chars long;
// if length = 0 (not specified) then the substring spans from
// startPosition until the end of this String
// throws an exception when startPosition is out of bounds
String Substring(int startPosition, int length) const
{
char * str = this->GetText();
String returnString;
int strLength = length;
int x = 0;
if(length == 0)
strLength = GetLength(str)-startPosition;
char* substring = new char[strLength];
// Makes sure the starting position is within the bounds of the String 'this'
try
{
CheckBounds(startPosition, str);
}
catch(char * error)
{
cout << error << endl << endl;
}
// In case the substring length is too long, it cuts short once it reaches the end of the original string. Yu-San, this is #2 on the three options you said I could implement, FYI.
while(x < strLength && str[x+startPosition]!='\0')
{
substring[x] = str[x + startPosition];
x++;
}
substring[x]='\0';
//for(int x = 0; x<strLength; x++)
//{
//returnString = str + startPosition;
returnString = substring;
//}
return returnString;
}
// Assignment operator to perform deep copy
String& operator = (const char* text)
{
// Ddispose of old Text
delete[] Text;
// +1 accounts for NULL-terminator
int trueLength = GetLength(text) + 1;
// Dynamically allocate characters on heap
Text = new char[trueLength];
// Copy all characters from source to Text; +1 accounts for NULL-terminator
for (int i = 0; i < trueLength; i++)
Text[i] = text[i];
return *this;
}
// Returns the count of characters in a C-string text; NULL-terminator is not counted
// static means that the member function neither reads nor
// writes any of the class' data members
// String::GetLength("blah");
static int GetLength(const char* text)
{
int x = 0;
while(text[x] != '\0')
x++;
return x;
}
// Returns a reference to a single character from this String
char& operator [] (int index) const
{
int length = GetLength();
// Check for valid index
if ((index < 0) || (index > length))
{
stringstream error;
error << "operator[] - index " << index << " is out of bounds (0.." << (length - 1) << ")";
throw String(error.str().c_str());
}
return Text[index];
}
// Returns the count of characters in the String; NULL-terminator is not counted
int GetLength() const
{
return GetLength(Text);
}
char* GetText() const
{
return Text;
}
// Finds first index of a symbol not found in "text" in string *this
int FindFirstNotOf(char * text)
{
String objectString(*this);
int x = 0; // loop counter
int firstIndex = 0; // index to return
while(text[x]!='\0')
{
// runs each character in 'text' against each character in the object.
for(int y = 0; y<objectString.GetLength(); y++)
{
if(objectString[x] == text[x])
objectString[x] = '\0';
}
x++;
}
while(objectString[firstIndex]=='\0' && (firstIndex<objectString.GetLength()))
{
firstIndex++; //keeps running until it Finds a character that wasn't changed to \0
}
if(firstIndex == objectString.GetLength())
firstIndex = -1; // means it wasn't found.
return firstIndex;
}
int FindFirstOf(char iWantThis)
{
String objectString(*this);
int firstIndex = 0; // index to return
while(objectString[firstIndex]!=iWantThis && (firstIndex<objectString.GetLength()))
{
firstIndex++; //keeps running until it Finds a character that wasn't changed to \0
}
if(firstIndex == objectString.GetLength())
firstIndex = -1; // means it wasn't found.
return firstIndex;
}
int FindLastOf(char iWantThis)
{
String objectString(*this);
int index = 0;
int lastIndex = -1;
while(objectString[index]!='\0')
{
if(objectString[index] == iWantThis)
lastIndex = index;
}
return lastIndex;
}
// finds a desired char in String object, with default start index of 0
int Find (char iWantThis, int startIndex = 0)
{
int index = -1;
int ctr = startIndex;
String objectString(*this);
while(objectString[ctr]!='\0' && index == -1) // runs until it reaches end, or the return index is changed
{
if(objectString[ctr] == iWantThis)
index = ctr;
else
ctr++;
}
return index;
}
private:
// Throws an String-type exception when index is out of bounds
void CheckBounds(int index, const char* source) const
{
int size = GetLength(source);
if(index < 0 && index >=size)
throw "Selected Starting Index is Out of Bounds.";
}
// The encapsulated C-string
char* Text;
};
// Stream output operator to print String to output stream
/* ostream& operator << (ostream& out, const String& myString)
* {
* return out << myString.GetText();
* };
*/
Двоичный 'operator <<' должен быть свободной функцией вместо функции-члена. Член 'operator <<' может принимать только один аргумент, который был бы правой частью выражения. У вас, кажется, есть оператор как бесплатная функция в качестве комментария в конце вашего кода. Почему эта попытка потерпела неудачу? – Pablo
@Pablo Спасибо за быстрый ответ. Существует несколько инструкций try/catch с оператором «<<» для проверки границ различных функций, а также другого кода проверки ошибок в классе. Он показывает ту же ошибку, что и «Ошибка 3». В верхней части страницы. Кроме того, спасибо за помощь в формате вопроса :) Когда перегрузка оператора является свободной функцией внизу, класс не знает, что означает «<<». Если я объявляю его вверху, я получаю сообщение об ошибке: «Ошибка C4430: спецификатор отсутствующего типа - предполагается int. Примечание: C++ не поддерживает значение по умолчанию -int« – Reciever80