Click here to Skip to main content
15,115,667 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
I want to make my own string class, for educational purposes (i am not a student, just like researching) and this should according to the internet be possible in C++, but i am unsure how.
Inside Mystring.h:
C++
class string {
private:
  char* data;
public:
  string& operator=(const char*& other) {
    if (data == other) {
      return *this;
    }
    else {
      data = (char*)other;
   }

Inside main.cpp:
C++
#include "Mystring.h"

int main(void) {
  string hello = "hi";
  return 0;
}

Ignore that the code is all in the header, i'm having some compiler problems.

The output:
../main.cpp:4:20: error: conversion from 'const char [3]' to non-scalar type 'string' requrested
  string hello = "hi";
Makefile:2: recipe for target 'default' failed
mingw32-make: *** [default] Error 1


What I have tried:

I have tried the above, but gets the error mentioned.
Posted
Updated 4 days ago

Even though the statement
C++
string hello = "hi"
looks like its an assignment, this is actually an object construction. The compiler is looking for a suitable constructor to create the object with, but only the default constructor is available, so compilation fails.

You have at least two options: either construct the object, then assign to it e.g.
C++
int main()
{
    string hello;   // calls default constructor for "string"
    hello = "hi";   // call string::operator=() 
}
or add a constructor to your string class that takes a const char * as an argument. In order to do that, we do have to jump through a couple of hoops to allow for the fact the "hi" is of type const char*
C++
class string {
   char *data;
   string() { }  // default constructor
   string(char *str) :  data(str)  { } //constructor for char *
   string(const char *str) {  //constructor for const char *
        data = const_cast<char *>(str);
   }
   string& operator=(const char* str) {
        if(data != str)
            data = str;
        return *this;
   }
};

int main()
{
    string hi = "hello";  // calls string::string(const char *) constrcutor
}

As noted earlier, we need to cast away constness for the constructor, which is a sign that we probably do not have good design for our data members. Casting away constness signals to the compiler that you "Know What You Are Doing", and the compiler can accept the code without complaint. Note that the object that string::data points to may still be a constant item, so if at some point you try to do something like this:
C++
class string {
   // ... other details omitted
   void captialize_first() {
     if(data)
        *data = toupper(*data);
  }
};

main()
{
    string hi = "hello";
    hi.capitilze_first();
} 
you will almost certainly get a program crash.*
*There may be some architectures and/or compiler combinations out there which do not implement string constants as constant objects, but as far as I know x86, x86-64, arm32 and arm64 all do.
   
v3
This line :

C++
data = (char*)other;


You do not want to do that, ever!

Do this instead:

C++
data = strdup((char*)other);


Because when anything passed in the assignment as a pointer you need to make a copy of that. The reason is when that "other" pointer is deleted, your data will be pointing into no man's land and next "data" access will crash.

So you just need a complete copy of that string and free it in your class destructor.
   
Comments
merano99 3 days ago
   
I fully agree with you. Before you overwrite the old pointer, you should definitely check whether you don't have to free up the memory beforehand.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)




CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900