C ++ производный конструктор класса - PullRequest
0 голосов
/ 18 октября 2018

Я изучаю наследование C ++, и у меня есть некоторые проблемы с ним.Я использую Zinjal IDE с компилятором GNU c ++.

Это код:

class String {
protected:
    char str[MAX_STR_SIZE];
public:
    String(char str_init[])
    {
        strcpy(str, str_init);
    }
};

class PString : String
{ 
    public:
    PString(char str_init[]) 
    {
        if (strlen(str_init) > MAX_STR_SIZE)
            strncpy(str, str_init, MAX_STR_SIZE-1);
        else
            String(str_init); 
    }
};

Ну, это просто создание моего собственного класса "string".Но: в чем проблема?Строка может пойти слишком много больше.Поэтому, когда конструктор моего класса «String» вызывается со строкой с суперсписанным «MAX_STR_SIZE» (которая для примера определяется как 80 символов), программа завершится с переполнением массива (> 80 символов).Поэтому я хочу создать «дочерний» или «производный» класс с именем «PString», который может обрабатывать переполнение.Как видите, конструктор дочернего класса PString проверяет строку, если она> MAX_STR_SIZE.Если он больше, чем тот массив символов, который может обработать его, обрежьте строку с помощью MAX_STR_SIZE, поэтому избегайте переполнения.Если он меньше, чем MAX_STR_SIZE, он вызывает конструктор класса Parent.Но g ++ не может сказать мне: «Нет соответствующего вызова функции для String :: String ()».

Это ошибка, которую я знаю, но я только учусь

Заранее спасибо.

Ответы [ 3 ]

0 голосов
/ 18 октября 2018

2 Ошибки.Во-первых, вам нужно вызвать базовый конструктор из списка инициализаторов вашего класса, как объяснено в этом ответе .

Во-вторых, вам нужно назначить некоторый объект вашему классу при вызове

String(str_init); 

Следующий код компилируется на моей машине.

#include <cstring>
#define MAX_STR_SIZE 20
class String {
protected:
    char str[MAX_STR_SIZE];
public:
    String(char str_init[])
    {
        std::strcpy(str, str_init);
    }
};

class PString : String
{ 
    public:
    PString(char str_init[]) : String(str_init) 
    {
        if (strlen(str_init) > MAX_STR_SIZE)
            strncpy(str, str_init, MAX_STR_SIZE-1);
        else
            String s = String(str_init); 
            String s2(str_init);
    int i = 0;
    i++;
    }
};
0 голосов
/ 18 октября 2018

то, что вы пытаетесь сделать, не требует этого набора осложнений.В целом strncpy будет правильно обрабатывать оба случая.Тем не менее, для образования приведу некоторый анализ

1.В вашем конструкторе PString вы вызываете конструкцию String и просите его strcpy str_intit в str.Таким образом, вы вызываете то же повреждение памяти, которое хотели избежать.вам не хватает String() конструктора.Я предлагаю создать конструктор по умолчанию для String и удалить тот, который вы используете из PString.

 String() {str[0] = 0;}
 ..
 PString(char str_init[])
 {

2.Ваш случай может быть немного изменен следующим образом:

if (strlen(str_init) > MAX_STR_SIZE) {
  strncpy(str, str_init, MAX_STR_SIZE-1);
  str[MAXLEN-1] = 0; // strncpy will not add '0' in this case. you need to do it yourself
}
else
  strcpy(str, str_init);

выше, в предложении if вы используете str n cpy, можете ли после 'else' использовать простой strcpy.Итак, это выглядит так:

#include <cstring>
#define MAX_STR_SIZE 80

class String {
protected:
  char str[MAX_STR_SIZE];
public:
  String(char *str_init)
  {
    strcpy(str, str_init);
  }
  String() {
   str[0] = 0;
  }
};

class PString : String
{ 
public:
  PString(char str_init[])
  {
    if (strlen(str_init) > MAX_STR_SIZE) {
      strncpy(str, str_init, MAX_STR_SIZE-1);
      str[MAX_STR_SIZE-1] = 0;
    }
    else
      strcpy(str, str_init);
  }
};
0 голосов
/ 18 октября 2018

Вы не можете просто вызвать конструктор на ровном месте.Есть только определенные места, которые можно вызвать конструктором, и это не одно из них.

Компилятор видит String(str_init); и предполагает, что это вызов функции, но у вас нет соответствующей функции - следовательно,ошибка.

Согласно комментарию ниже, здесь есть тонкость.Сообщение об ошибке: «Нет соответствующего вызова функции для String :: String ()».В классе с именем String метод с именем String будет конструктором.Поэтому строка String(str_init); не является вызовом функции, она пытается создать элемент String с использованием несуществующего конструктора по умолчанию.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...