Trevin Corkery Trevin Corkery - 1 month ago 7
C++ Question

C++ - Accessing char* with &String[0] on class

I was just experimenting and making my own string class. (Mainly because there is some stuff I wanted to build in custom methods like "toBase64" etc. Anyways, I was wondering how you could access the private member of char* when you use &String[0].

I thought you could use operator-overloading but I currently only have it as String[0] returns the char*. (I know & is the pointer operator).

String.h

namespace CoffeeBeans
{
class _declspec(dllexport) Coffee_String
{
char* String;
int StringLength;

public:
Coffee_String();
Coffee_String(LPCSTR CString);

LPSTR operator[](int);

~Coffee_String();
};
}


String.cpp

#include "stdafx.h"
#include "String.h"
#include <Windows.h>

CoffeeBeans::Coffee_String::Coffee_String() {
this->String = nullptr;
this->StringLength = 0;
}

CoffeeBeans::Coffee_String::~Coffee_String() {

if (String != nullptr) {
delete[] this->String;
this->String = nullptr;
this->StringLength = 0;
}
}

CoffeeBeans::Coffee_String::Coffee_String(LPCSTR CString) {

int StringLength = strlen(CString) + 1;

this->String = new char[StringLength]();
this->StringLength = StringLength - 1;
memcpy_s(this->String, StringLength, CString, StringLength);
}

LPSTR CoffeeBeans::Coffee_String::operator[](int)
{
return this->String;
}


Main.cpp

case WM_CREATE:{
CoffeeBeans::Coffee_String String("Test");

//I want to be able to do
//strcpy_s(&String[0], 3, "hi"); //Copy "hi" into the private variable char*String.
//I know this isn't a practical use, I wanted quick example (I would really pass it to recv (WinSock2))

MessageBeep(0);

break;
}

Answer

Your operator[] is returning the wrong value. In order for &String[index] to access the correct memory address, operator[] needs to return a reference to the character at the specified index, not return the string pointer itself, as you are currently doing.

If you look at the actual declaration of std::string::operator[], you will see that it returns a std::string::reference (aka char &) or std::string::const_reference (aka const char &) (depending on whether it is being called on a non-const or const std::string object).

Try something more like this:

String.h

namespace CoffeeBeans
{
    class _declspec(dllexport) Coffee_String
    {
        char* String;
        int StringLength;

    public:
        Coffee_String();
        Coffee_String(const Coffee_String &src);
        Coffee_String(const char *src);
        ~Coffee_String();

        char& operator[](int index);
        const char& operator[](int index) const;

        Coffee_String& operator=(const Coffee_String &rhs);
    };
};

String.cpp

#include "stdafx.h"
#include "String.h"
#include <algorithm>
#include <cstring> 

CoffeeBeans::Coffee_String::Coffee_String() {
    String = nullptr;
    StringLength = 0;
}

CoffeeBeans::Coffee_String::Coffee_String(const CoffeeBeans::Coffee_String &src) {
    StringLength = src.StringLength;
    String = new char[StringLength+1];
    std::copy(src.String, src.String+StringLength, String);
    String[StringLength] = 0;
}

CoffeeBeans::Coffee_String::Coffee_String(const char *src) {
    StringLength = std::strlen(str);
    String = new char[StringLength+1];
    std::copy(src, src+StringLength, String);
    String[StringLength] = 0;
}

CoffeeBeans::Coffee_String::~Coffee_String() {
    delete[] String;
    String = nullptr;
    StringLength = 0;
}

char& CoffeeBeans::Coffee_String::operator[](int index)
{
    return String[index];
}

const char& CoffeeBeans::Coffee_String::operator[](int index) const
{
    return String[index];
}

CoffeeBeans::Coffee_String& CoffeeBeans::Coffee_String::operator=(const CoffeeBeans::Coffee_String &rhs);
{
    Coffee_String temp(rhs);
    std::swap(String, temp.String);
    std::swap(StringLength, temp.String);
    return *this;
}

Main.cpp

case WM_CREATE: {
    CoffeeBeans::Coffee_String String("Test");

    strcpy_s(&String[0], 3, "hi"); //Copy "hi" into the private variable char *String...
    // note that the content of String will become "hi\0t\0", not "hi\0"
    // and StringLength will still be 4...

    MessageBeep(0);

    break;
}