Построение строк без std :: string - PullRequest
0 голосов
/ 13 февраля 2019

Я работаю над проектом, в котором нам вообще не разрешено использовать библиотеку <string> - мы можем работать только со строками в качестве символьных указателей, и мы должны написать свои собственные функции для них (strcpy, strlen,так далее).Я пытаюсь создать класс RentalCar со следующим заголовочным файлом:

#ifndef RENTALCAR_H
#define RENTALCAR_H
class RentalCar {
 public:
  RentalCar();
  RentalCar(char* make, char* model);
  char* getMake() const;
  char* getModel() const;
  void setMake(char* make = "");
  void setModel(char* model = "");
 private:
  char m_make[256];
  char m_model[256];
};
#endif

Мой исходный файл содержит следующее:

#include <iostream>
#include "RentalCar.h"
using namespace std;

RentalCar::RentalCar() {
    setYear();
    setMake();
    setModel();
    setPrice();
    setAvailable();
}

RentalCar::RentalCar(int year, char* make, char* model, float price, 
bool available) {
    setYear(year);
    setMake(make);
    setModel(model);
    setPrice(price);
    setAvailable(available);
}

char* RentalCar::getMake() const{
    return m_make;
}

char* RentalCar::getModel() const{
    return m_model;
}

void RentalCar::setMake(char* make) {
    myStringCopy(m_make, make);
}

void RentalCar::setModel(char* model) {
    myStringCopy(m_model, model);
}


char* myStringCopy(char* destination, const char* source) {
    int index = 0;
    while(*(source + index) != '\0') {
        *(destination + index) = *(source + index);
        index++;
    }
    *(destination + index) = '\0';
    return destination;
}

Моя проблема в том, что я получаю следующееошибка в моих методах getMake и getModel:

cannot initialize return object of type 'char *'
  with an lvalue of type 'char const[256]'

Я не уверен, как создать строки по умолчанию, не делая их литералами - вот почему я думаю, что я получаю эту ошибку.

Мой другой вопрос заключается в том, что для установки строк в моих функциях setMake () и setModel () мне нужно использовать функцию myStringCopy (), поэтому я должен включить ее в качестве функции в этом классе,или есть способ получить к нему доступ иначе?Мне также нужно использовать его в моем текущем файле проекта, и его необходимо включать туда и в RentalCar.cpp *

Стоит отметить, что мы не можем работать со строками, используя индексацию массива в любомспособ - кроме как для инициализации новой строки.

Любая помощь будет оценена!Спасибо!

Ответы [ 2 ]

0 голосов
/ 13 февраля 2019

KitsuneYMG отвечает на ваши проблемы с компиляцией.Я хочу немного подробнее рассказать о вашем коде.

Во-первых, этот код проще.

char* myStringCopy(char* destination, const char* source) {
    char * retVal = destination;
    do {
        *(destination++) = *(source++);
    } while ( *(source++) != 0 );
    return retVal;
}

Но если вы хотите использовать свой код, это также более понятно:

char* myStringCopy(char* destination, const char* source) {
    int index = 0;
    while(source[index] != '\0') {
        destination[index] = source[index];
        index++;
    }
    destination[index] = '\0';
    return destination;
}

Но это довольно симпатичный способ немного изменить это:

char* myStringCopy(char* destination, const char* source) {
    int index = 0;
    do {
        destination[index] = source[index];
    } while (source[index++]);

    return destination;
}

Далее.Это важно, если вы хотите быть настоящей программой.Буферы фиксированной длины - действительно очень плохая идея, особенно если вы не проверяете длину входных строк.Если ваши данные должны были включать строки из 256 символов (или более), то ваши 256 байтов не будут содержать строку плюс 0 байтов, и у вас будет повреждение данных.

Это очень распространенная ситуацияпроблема в коде, который опирается на буферы фиксированной длины.Это называется переполнением буфера и является одним из самых больших методов, которые хакеры используют для взлома программного обеспечения.Огромные проблемы с безопасностью.

Если вы собираетесь использовать буферы фиксированной длины вместо того, чтобы учиться использовать new [] и delete [], то вам нужно проверить длину входных данных для ваших сеттеров.

0 голосов
/ 13 февраля 2019
char* getMake() const;
char* getModel() const;

Говорит, что вы можете вернуть указатель на изменяемое значение, даже если класс неизменен.Трейлинг const в объявлениях функций означает, что эта функция должна работать, когда класс в целом является const, что означает, что все * члены выбирают ключевое слово const.

const char* getMake() const { return m_make; }
const char* getModel() const { return m_model; }
char* getMake() { return m_make; } 
char* getModel(){ return m_model; }

должно работать.const версии класса получают неизменяемые значения, но не- const - нет.Хотя возврат не const указателей нарушает инкапсуляцию.Так что я просто сделаю:

const char* getMake() const { return m_make; }
const char* getModel() const { return m_model; }

и оставлю это на этом.И изменяемая, и неизменяемая версии класса будут получать неизменяемые значения из ваших функций get.Это, вероятно, желаемый результат.

* mutable говорит привет и затем уходит в угол, чтобы умереть.

...