2016-11-03 7 views
0

Я просто экспериментировал и создавал свой собственный класс строк. (В основном потому, что есть некоторые вещи, которые я хотел создать в пользовательских методах, таких как «toBase64» и т. Д. В любом случае мне было интересно, как вы можете получить доступ к частному члену char *, когда используете & String [0].C++ - Доступ к char * with & String [0] в классе

Я думал вы можете использовать оператор-перегружать, но я в настоящее время это только как String [0] возвращает символ *. (Я знаю, что & оператор указатель).

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; 
} 
+0

В чем проблема вы переживает? – 0x499602D2

+1

Все эти 'this->' s - просто шум. Избавься от них. В деструкторе вам не нужно проверять, является ли 'String' NULL; 'delete', которые просто отлично. И в деструкторе нет смысла устанавливать 'String' в NULL и' StringLength' в 0; объект уходит, и никто не может видеть эти значения. –

+0

@PeteBecker в порядке Я удалю это из моего деструктора, и меня просто научили из моей книги, что использование этого-> было хорошей привычкой, потому что он знает, что вы имеете в виду этот объект и т. Д. –

ответ

3

Ваш operator[] возвращает неверное значение. Для того, чтобы получить адрес &String[index] для доступа к правильному адресу памяти, operator[] должен вернуть ссылку на символ по указанному индексу, а не возвращать сам указатель строки, как вы сейчас делаете.

Если вы посмотрите на фактическое объявление std::string::operator[], вы увидите, что она возвращает std::string::reference (ака char &) или std::string::const_reference (ака const char &) (в зависимости от того, что называется на неконстантных или константную std::string объекта) ,

Попробуйте что-то больше, как это:

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; 
} 
+0

Спасибо! я очень ценю это –