4

I'm working on a project where we're not allowed to use the <string> library at all - we can only work with strings as character pointers and we have to write our own functions for them(strcpy, strlen, etc). I'm trying to construct a RentalCar class with the following header file:

#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

My source file contains the following:

#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;
}

My problem is that I'm getting the following error in my getMake and getModel methods:

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

I'm not sure how to construct default strings without making them literals - which is why I think I'm getting this error.

My other question is that in order to set the strings in my setMake() and setModel() functions, I need to use my myStringCopy() function, so should I include it as a function in this class, or is there a way to get access to it otherwise? I also need to use it in my actual project file and it feels redundant to include it there and in the RentalCar.cpp as well

It's worth mentioning we're not allowed to work with strings using array indexing in any way - except to initialize a new string.

Any help would be appreciated! Thank you!

15
  • 10
    To get around the problem I would write my own string class. It doesn't need to be as extensive as std::string but encapsulating the string management and comparison makes the code that uses it so much easier to write. Commented Feb 13, 2019 at 14:08
  • 8
    @BRetnik That's a real bummer. It's a shame so many classes don't actually teach C++ when they are teaching C++. Commented Feb 13, 2019 at 14:20
  • 3
    @BRetnik -- and they have to be stored as char[] specifically, not a String object -- So you get points taken off for doing more work in creating a String class? What you're being taught is how to easily create buffer overruns, thus unsecure code -- something that a good C++ course should not be teaching. I can bet that after this course, many students will now use Java, Python, or C#, and drop C++ forever. Commented Feb 13, 2019 at 14:34
  • 3
    Given this day and age, I am surprised that there are not a lot of teachers saying "this is really bad teaching students like this", and thus (at the very least) spark a discussion among their peers.. How do you explain this passiveness of C++ teachers to speak up? You're being taught garbage, unless there is a rhyme or reason to teaching you "bad code" and you will get a comparison to well written code later on. Commented Feb 13, 2019 at 14:51
  • 1
    @MikeBorkland Granted, but C++ was standardized 20 years ago, thus std::string has been available since then. That is a generation now. Could you imagine a TV repair course teaching how to replace vacuum tubes? Commented Feb 13, 2019 at 15:28

2 Answers 2

3
char* getMake() const;
char* getModel() const;

Says that you can return a pointer to a mutable value even when the class is immutable. The trailing const on the function declarations means this function specifically must work when the class as a whole is const, which means all* members pick up the const keyword.

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

should work. const versions of the class with get the immutable values, but non-const won't. Although, returning non-const pointers breaks encapsulation. So I'd just do:

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

and leave it at that. Both mutable and immutable versions of the class will get immutable values from your get functions. This is probably the desired result.

* mutable says hi and then slinks off to a corner to die.

Sign up to request clarification or add additional context in comments.

Comments

1

KitsuneYMG answers your compilation problem. I want to talk about your code a little further.

First, this code is simpler.

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

But if you want to use your code, this is also more understandable:

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

But this is kind of a cute way to turn it around a little:

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

    return destination;
}

Next. This is important if you want to be a real program. Fixed-length buffers are a really really bad idea, especially if you don't check the lengths of your input strings. If your data were to include strings of 256 characters (or more), then your 256 bytes won't hold the string plus the 0-byte, and you'll have data corruption.

This is a very common problem in code that relies on fixed length buffers. It's referred to as a buffer overrun, and is one of the biggest methods hackers use to break software. Huge security problems.

If you are going to use fixed-length buffers instead of learning how to use new[] and delete[], then you need to length-check the input to your setters.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.