Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > C/C++ программирование > Общие вопросы C/C++
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 08.02.2013, 14:07   #1
Borkot
Пользователь
 
Аватар для Borkot
 
Регистрация: 29.04.2012
Сообщений: 37
По умолчанию Немного не разобрался в перегрузке []

Привет всем!
Спасибо заранее всем! Если Я передаю по ссылке то и возвращать нужно ссылку.
Значит в фукции main() сделать присваивание.
Подчеркивает return s[k];Мне кажется что-то делаю не так.

файл MyString.h
Код:
#pragma once
#include"stdafx.h"
class MyString
{
	char s[255];
public:
	MyString(void);
	~MyString(void);
	void Show(void) const;
	void SetString();
	char &operator [](int k)const;
};

MyString.cpp
Код:
#include "MyString.h"


MyString::MyString(void)
{
	strcpy(s,"Привет люди человеки!");
}


MyString::~MyString(void)
{
}

void MyString::Show(void) const
{
  cout<<"s= "<<s<<endl<<flush;
}

void MyString::SetString()
{
   gets(s);
}
char &MyString::operator [](int k)const
{
	 int p=strlen(s);
	 if(k<0)
		 cout<<"\n"<<*s<<"\n";
	 else
	 {
		 if(k>p)
			 cout<<"\n"<<s[p-1]<<"\n";
		 else 
			 return s[k]; 
	 }
}
Borkot вне форума Ответить с цитированием
Старый 08.02.2013, 14:08   #2
Borkot
Пользователь
 
Аватар для Borkot
 
Регистрация: 29.04.2012
Сообщений: 37
По умолчанию

в stdafx.h
Цитата:
#pragma once
#include<iostream>
#include<string.h>
using namespace std;
Borkot вне форума Ответить с цитированием
Старый 08.02.2013, 14:10   #3
Borkot
Пользователь
 
Аватар для Borkot
 
Регистрация: 29.04.2012
Сообщений: 37
По умолчанию

Извините задачу забыл вылоджить задача такая обратится к массиву к конкретному элементу с помощью перегрузки оператора [] .ну и проверять что- бы не выходи за пределы.
Borkot вне форума Ответить с цитированием
Старый 08.02.2013, 14:46   #4
Abstraction
Старожил
 
Аватар для Abstraction
 
Регистрация: 25.10.2011
Сообщений: 3,178
По умолчанию

Моя не понял, чего у Вас в operator[] делает cout.
Что печальнее, поскольку метод помечен как константный, то и s имеет тип const char[]. А поскольку Вы возвращаете неконстантную ссылку на элемент массива, компилятор начинает ругаться самыми чёрными словами.
С другой стороны, если возвращать константную ссылку, нельзя будет написать
myStr[2] = 'a';
Поэтому нужно - так (по-хорошему, надо бы кидать исключение за такие обращения, ну да ладно):
Код:
const char& MyString::operator[](int k)const {
  static char trash = '\0';
  if(k<0 || k>=strlen(s)){
    std::cerr << "MyString::operator[] - Index out of bounds!" << std::endl; 
    return trash;
  }
  return s[k];
}

char& MyString::operator[](int k) {
  return const_cast<char&>(const_cast<const MyString&>(*this)[k]);
}

Последний раз редактировалось Abstraction; 08.02.2013 в 14:49.
Abstraction вне форума Ответить с цитированием
Старый 08.02.2013, 23:22   #5
_SOKOL_
Пользователь
 
Регистрация: 02.02.2013
Сообщений: 44
По умолчанию

поменяй
char &operator [](int k)const;
на
char *operator [](int k)const;

когда возвращаешь строку, то надо возвращать указатель, так как массив сам по себе и есть указатель
_SOKOL_ вне форума Ответить с цитированием
Старый 09.02.2013, 10:59   #6
waleri
Старожил
 
Регистрация: 13.07.2012
Сообщений: 6,331
По умолчанию

Цитата:
Сообщение от _SOKOL_ Посмотреть сообщение
поменяй
char &operator [](int k)const;
на
char *operator [](int k)const;

когда возвращаешь строку, то надо возвращать указатель, так как массив сам по себе и есть указатель
В принципе можно так сделать, но не нужно, иначе надо будет помнить, что для этого класса результат [] отличается.
Если у нас есть char* ptr то какой тип возвращается при ptr[123]?
Если у нас есть char ptr[123] то какой тип возвращается при ptr[123]?
Тем более, что соль не в том, чтоб вернуть строку а символ из строки, при чем так, чтоб можно было использовать и как lvalue
waleri вне форума Ответить с цитированием
Старый 09.02.2013, 15:28   #7
_SOKOL_
Пользователь
 
Регистрация: 02.02.2013
Сообщений: 44
По умолчанию

Цитата:
Сообщение от waleri Посмотреть сообщение
В принципе можно так сделать, но не нужно, иначе надо будет помнить, что для этого класса результат [] отличается.
Если у нас есть char* ptr то какой тип возвращается при ptr[123]?
Если у нас есть char ptr[123] то какой тип возвращается при ptr[123]?
Тем более, что соль не в том, чтоб вернуть строку а символ из строки, при чем так, чтоб можно было использовать и как lvalue
в таком случае перегрузку делаем так
char operator[] (int k) const;
если нужно вернуть один символ, то возвращаем просто char, зачем возвращать ссылку или указатель?
_SOKOL_ вне форума Ответить с цитированием
Старый 09.02.2013, 23:33   #8
Abstraction
Старожил
 
Аватар для Abstraction
 
Регистрация: 25.10.2011
Сообщений: 3,178
По умолчанию

Цитата:
если нужно вернуть один символ, то возвращаем просто char, зачем возвращать ссылку или указатель?
Тогда
Цитата:
нельзя будет написать
myStr[2] = 'a';
Точнее, написать-то будет можно, но вот результат окажется далёк от ожидаемого.
Abstraction вне форума Ответить с цитированием
Старый 10.02.2013, 02:35   #9
denrubun
Пользователь
 
Регистрация: 24.12.2012
Сообщений: 82
По умолчанию

sizeof(char) == 1 байт
sizeof(указатель) == 4 байт
ссылка это тоже указатель.
спрашивается: зачем возвращать ссылку?( только в случае char!!)

отсюда: const char operator[] (int k) const; (для rvalue)

для lvalue правильнее будет возвращать ссылку, т.к. с ней работать(синтаксически) так же как с символом, а вот с указателем как раз куча проблем и отличий возникает.

отсюда: char &operator[] (int k); (для lvalue)

два метода полюбому реализовывать придется от этого не уйти
denrubun вне форума Ответить с цитированием
Старый 10.02.2013, 18:06   #10
Abstraction
Старожил
 
Аватар для Abstraction
 
Регистрация: 25.10.2011
Сообщений: 3,178
По умолчанию

Цитата:
спрашивается: зачем возвращать ссылку?( только в случае char!!)
Ну, во-первых, мы тогда лишаемся возможности в неконстантной версии метода сослаться на константную; во-вторых, отнюдь не очевидно, что Ваш вариант оптимальнее:
1) Возвращаем ссылку. В функции - взять адрес начала массива, прибавить требуемое смещение, вернуть адрес (thiscall возвращает результат в eax). В вызывающем коде - обратиться по адресу, прочитав значение в другой регистр.
2) Возвращаем значение. В функции - взять адрес начала массива, прибавить смещение, обратиться по адресу, вернуть значение. В вызывающем коде просто использовать значение.
Т.е. проделывается один и тот же набор действий, в общем-то.
Abstraction вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Ошибка при перегрузке << и >> DartDayring Visual C++ 8 07.12.2020 13:42
Завтра экзамен, а я не разобрался с задачей( Getman Помощь студентам 6 01.02.2012 20:39
С теорией я разобрался незнаю как реализовать Valerii Assembler - Ассемблер (FASM, MASM, WASM, NASM, GoASM, Gas, RosAsm, HLA) и не рекомендуем TASM 2 26.01.2010 15:35
MASM: HelloWorld разобрался в коде, поправьте немного N!ckeL Помощь студентам 6 25.02.2009 22:03