0

I compiled very simple code, but I couldn't compile this code.

#include <iostream>

using namespace std;

class String {
    char *str;
public:
    String(char *);
    ~String();
    char *get() { return str; }
};

String::String(char *p)
{
    cout << " ! constructor\n";
    str = new char[strlen(p) + 1];
    strcpy(str, p);
}

String::~String()
{
    cout << " ! destructor\n";
    delete str;
}

void show1(String &s)
{
    cout << "show1 : " << s.get();
}
void show2(String s)
{
    cout << "show2 : " << s.get();
}
int main()
{
    char *str = "C++ Language";
    String ss(str);

    show1(ss); cout << endl;
    show2(ss); cout << endl;

    return 0;
}

error say it can't be converted const char [13] to char * . how can I compile this code? I compile this with visual studio.

favdew
  • 21
  • 1
  • 2
  • 5
  • You could change `char *str = "C++ Language";` to `char str[]="C++ Language;"` Initializing the pointer directly with constant string is not supported by most compilers. – Wander3r Aug 03 '18 at 09:12
  • 1
    Use std::string in C++ – Clonk Aug 03 '18 at 09:13
  • Related question: https://stackoverflow.com/questions/20944784/why-is-conversion-from-string-constant-to-char-valid-in-c-but-invalid-in-c/20944858 – vishal Aug 03 '18 at 09:18
  • 1
    Don't write your own string class. We already have too many of them – Caleth Aug 03 '18 at 09:20
  • This doesn't address the question, but `delete str;` in the destructor should be `delete [] str;`. `str` was allocated as an array, so has to be deleted as an array. In practice the code as written usually works for types that don't have a destructor, but that's not something you should rely on. – Pete Becker Aug 03 '18 at 11:31

3 Answers3

1

As you only want to read the string, you want it to be const. Change

String::String(char *p)
    ...
char *str = "C++ Language";

to

String::String(const char *p)
    ...
const char *str = "C++ Language";
Gem Taylor
  • 5,381
  • 1
  • 9
  • 27
1

String literals are constant and shouldn't be modified, older compilers might allow assigning them to char * but more modern compilers will only allow assignment to const char* (or const char[]), e.g. this should compile:

const char *str = "C++ Language";

Even if your compiler allows assignment to char * you should always use const char* to prevent hard to trace crashes when you try to modify a string literal.

Alan Birtles
  • 32,622
  • 4
  • 31
  • 60
  • 2
    C compilers, not "older compilers". It has never been correct C++ to assign a string literal to a `char *` – Caleth Aug 03 '18 at 09:22
  • @Caleth that may be true but older compilers might not have fully implemented the c++ standard (in fact most current compilers probably aren't fully compliant with c++), I think older versions of gcc certainly allowed this. – Alan Birtles Aug 03 '18 at 09:24
  • e.g. gcc 4.8.4 allows it with a deprecation warning – Alan Birtles Aug 03 '18 at 09:26
  • 1
    In a very real sense that *isn't* a C++ compiler. It's a compiler for a language that is easily mistakable for C++ – Caleth Aug 03 '18 at 09:28
  • @Caleth testing with https://godbolt.org/ no compiler rejects assignment of literals to non const and only clang and gcc warn about it. Testing with VC 2017 locally it does reject the assignment with an error, – Alan Birtles Aug 03 '18 at 09:46
  • 1
    They issue a diagnostic, telling you your program isn't C++. That they still give you an executable doesn't change what C++ is defined as – Caleth Aug 03 '18 at 09:51
-2

Include string.h for strlen and strcpy