Модераторы: bsa
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Задача из учебника Лафоре, Задача по наследованию классов из Лафоре 
:(
    Опции темы
Zerstroer
Дата 6.9.2011, 14:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 285
Регистрация: 8.8.2007
Где: Алма-Ата

Репутация: 1
Всего: 3



Здравствуйте.
Решил взяться порешать задачки по C++. Систематизировать мусор в голове. В качестве задачника решил использовать учебник Роберта Лафоре "ООП в С++".
При решении задач из главы 9 возник ряд вопросов. Прошу более опытных товарищей помочь.

Вопрос первый.
Упражнение 2, главы 9.
Нижеприведенный листинг взят из правильных решений с сайта издательства книги:

Код

// ex9_2.cpp
//inheritance from String class
#include <iostream>
#include <cstring>                //for strcpy(), etc.
using namespace std;               
////////////////////////////////////////////////////////////////
class String                      //base class
   {
   protected:                     //Note: can't be private
      static const int SZ = 10;         //size of all String objects
      char str[SZ];               //holds a C-string
   public:
      String()                    //constructor 0, no args
         { str[0] = '\0'; }
      String( char s[] )          //constructor 1, one arg
         { strcpy(str, s); }      //  convert string to String
      void display() const        //display the String
         { cout << str; }
      operator char*()            //conversion function
         { return str; }          //convert String to C-string
   };
////////////////////////////////////////////////////////////////
class Pstring : public String     //derived class 
   {
   public:
      Pstring( char s[] );        //constructor
   };
//--------------------------------------------------------------
Pstring::Pstring( char s[] )      //constructor for Pstring
   {
   if(strlen(s) > SZ-1)           //if too long,
      {
      for(int j=0; j<SZ-1; j++)   //copy the first SZ-1
         str[j] = s[j];           //characters "by hand"
      str[j] = '\0';              //add the null character
      }
   else                           //not too long,
      String(s);                  //so construct normally //Не работает использую strcpy(str, s); 
   }
////////////////////////////////////////////////////////////////
int main()
   {                                        //define String
   Pstring s1 = "This is a very long string which is probably "
          "no, certainly--going to exceed the limit set by SZ.";
   cout << "\ns1="; s1.display();           //display String

   Pstring s2 = "This is a short string.";  //define String
   cout << "\ns2="; s2.display();           //display String
   cout << endl;
   return 0;
   }


Проблема возникает при вызове из конструктора класса Pstring::Pstring( char s[] ) конструктора родительского класса String(s).
Вместо конструктора с одним аргументом  String( char s[] ), в данном месте вызывается конструктор родительского класса БЕЗ аргументов String().
С чем эта ситуация связана?

Вопрос 2.
Уражнение 8, главы 9.
Задание:
8. В некоторых языках, таких как Visual Basic, есть операции, с помощью которых можно выделить часть строки и присвоить её другой строке. (В стандартном классе string предложены различные подходы. Использую наследование, добавьте такую возможность в класс Pstring из упражнения 2 (листинг решенного упражнения я выложил выше). В новом производном классе Pstring2 разместите три новых функции: left(), mid() и right().
s2.left(s1, n) //В строку s2 помещаются n самых левых символов строки s1
s2.mid(s1, s, n) //В строку s2 помещаются n символов из строки, начиная с символа номер s
s2.right(s1, n) //В строку s2 помещаются n самых правых символов строки s1
Вы можете использовать цикл for для копирования символ за символом подходящих частей строки s1 во временный объект класса Pstring2, который затем их возвратит. Для получения лучшего результата используйте в этих функциях возврат по ссылке, что бы они могли быть использованы с левой стороны знака "равно" для изменения части существующей строки.

Вот текст задания.

Решение выполнил так:
Код

#include <cstdlib>
#include <string.h>
#include <iostream>

using namespace std;

class String_                      //base class
   {
   protected:                     //Note: can't be private
      static const int SZ = 10;           //size of all String objects
      char str[SZ];               //holds a C-string
   public:
      String_()                    //constructor 0, no args
         { str[0] = '\0'; }
      String_( char s[] )          //constructor 1, one arg
         { strcpy(str, s); }      //  convert string to String
      void display() const        //display the String
         { cout << str; }
      operator char*()            //conversion function
         { return str; }          //convert String to C-string
   };
////////////////////////////////////////////////////////////////
class Pstring : public String_     //derived class 
   {
   public:
      Pstring( char s[] );        //constructor
   };
//--------------------------------------------------------------
Pstring::Pstring( char s[] )      //constructor for Pstring
   {
   if(strlen(s) > SZ-1)           //if too long,
      {
       int jj;
      for(int j=0; j<SZ-1; j++){   //copy the first SZ-1
         str[j] = s[j];           //characters "by hand"
         jj = j;
      }
      str[jj] = '\0';              //add the null character
      }
   else {                          //not too long,
      strcpy(str, s);                  //so construct normally
   }  
   }

class Pstring2: private Pstring{
public:    
    Pstring2& left(Pstring2 s1, int n){
        int j;
        for (int i = 0; i<n+1; i++){
            str[i] = s1.str[i];
            j=i;
        }    
        str[j] = '\0';
    }
  
    Pstring2& mid(Pstring2 s1, int s, int n){
        int j;
        for (int i=s; i<n+1; i++){
            str[i-s] = s1.str[i];
            j = i;
        }
        str[j]='\0';
      //  return Pstring2(str);
    }
    
    Pstring2& right(Pstring2 s1, int n){
      int j;
      int l = strlen(s1.str);
      for (int i = 0; i < n+1; i++){
          str[i] = s1.str[l-n+i];
          j = i;
      }
      str[j] = '\0';
    //  return Pstring2(str);
    }
    
    void display() const{
        Pstring::display();
    }
    
    Pstring2(char s[]):Pstring(s){
    }
};


Возникла сложность с "возвратом по ссылке", для получения возможности использовать слева от знака "равно". Как это правильно реализовать в контексте данной задачи? Прошу привести, если есть возможность пример. У Лафоре эта тема затронута вскользь, самостоятельно освоить, как видите, терпения не хватило.
Заранее спасибо.


--------------------
In silico
PM MAIL ICQ   Вверх
Result
Дата 6.9.2011, 20:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 52
Регистрация: 15.5.2011

Репутация: 3
Всего: 5



По первому вопросу: 
Нужно в списке инициализации дочернего класса передавать параметр(ы) 
в конструктор базового

Код

Pstring::Pstring( char s[] ):String(s) 
   {
        ...
   }


Когда список инициализации не задан, для подходящих членов классов, будут вызваны
конструкторы по умолчанию т.е. примерно так (только есть особенности когда подставляются нули):

Код

Pstring::Pstring( char s[] ):String(), член-класса()
   {
        ...
   }


Что является полным соответствием (высший приоритет при разрешении перегрузки) конструктору по умолчанию 
базового класса.

Это сообщение отредактировал(а) Result - 6.9.2011, 20:37
PM   Вверх
Zerstroer
Дата 7.9.2011, 18:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 285
Регистрация: 8.8.2007
Где: Алма-Ата

Репутация: 1
Всего: 3



Благодарю Resut за точное объяснение половины проблемы.
Относительно второй части вопроса, нашел некое подобие объяснения вот здесь:
Решение проблемы на другом форуме
Суть приблизительно понял (относительно указателей, еще не читал), но с реализацией верной возникли проблемы.
Пока остановился вот на этом:
  
Код

  Pstring2& left(Pstring2 s1, int n){
        Pstring2* nstr = (Pstring2*)new Pstring2(s1);
        //Pstring2 nstr(s1);
        int j;
        for (int i = 0; i<n+1; i++){
            nstr->str[i] = s1.str[i];
            //str[i] = s1.str[i];
            j=i;
        }    
        //str[j] = '\0';
        nstr->str[j] = '\0';
        return *nstr;
    }


Однако, желаемого эффекта всё же не достиг.


--------------------
In silico
PM MAIL ICQ   Вверх
mes
Дата 7.9.2011, 19:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 79
Всего: 250



слишком много воды и не видно сути вопроса.. 
но new использованное в последнем коде однозначно лишнее.. 
Если left должно изменить содержимое объекта к которому ее применяете, то this в помощь..

Добавлено через 1 минуту и 39 секунд
если проблема в том, что при возвращении *this, какие то проблемы с результатом, то скорей всего накосячили с констуркторами.. 
алсо, вначале, сформулируйте четко вопрос и даже Вам самим станет понятно, где искать на него ответ.. 


--------------------
PM MAIL WWW   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "C/C++: Для новичков"
JackYF
bsa

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

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

  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, JackYF, bsa.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Для новичков | Следующая тема »


 




[ Время генерации скрипта: 0.0887 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.