Accessing a private member...

SephirothSephiroth Fayetteville, NC, USA
Alright, I know a class can access its own private members and nothing else can, but what if I wanted to return a private member using a public method? For example, I create an array of chars in a class which are private. The end-developer may need to view this data for some reason. I return a pointer to that array through a public method. Could the developer use the pointer to change that data, or just read it?
[code]
class MyFakeClass
{
public:
MyFakeClass();
~MyFakeClass();
char* ReturnMessage();

private:
char *pBuffer;
};

MyFakeClass::MyFakeClass()
{
this->pBuffer = new char[1024];
sprintf(this->pBuffer, "This is a pointless message!");
}

MyFakeClass::~MyFakeClass()
{
delete[] this->pBuffer;
}

char* MyFakeClass::ReturnMessage()
{
return this->pBuffer;
}

//Somewhere in the main program loop...
char *pText;
MyFakeClass *pTemp;

pTemp = new MyFakeClass;
pText = pTemp->ReturnMessage();
sprintf(pText, "This should cause an error!");
[/code]
Would the sprintf() call crash the program or throw an exception as it should, or will it simply overwrite the text in the array, which it shouldn't?

-[italic][b][red]S[/red][purple]e[/purple][blue]p[/blue][green]h[/green][red]i[/red][purple]r[/purple][blue]o[/blue][green]t[/green][red]h[/red][/b][/italic]

Comments

  • Returning pointers from classes (or even from function) is poor design in 99% of the cases. Especially pointers to dynamically allocated data. And especially if the class member is private: if you return a pointer to privates you have efficiently removed the concept of encapsulation.

    Always make a hard copy of the data when you read to/from a class. This doesn't necessarily mean you have to pass parameters by value on the stack. The best way is usually to leave the allocation to the caller: if the caller is doing something with a chunk of data, it is the callers business to handle the allocation too, your class/function doesn't need to concern itself with it.

    Something like this is what I'd recommend for amounts of data that are too large to pass by value:

    [code]void get_data (unsigned char* data, size_t n)
    {
    memcpy(data, private_data, n);
    }[/code]

    That goes for both C and C++.
  • SephirothSephiroth Fayetteville, NC, USA
    : Something like this is what I'd recommend for amounts of data that
    : are too large to pass by value:
    :
    : [code]: void get_data (unsigned char* data, size_t n)
    : {
    : memcpy(data, private_data, n);
    : }[/code]:
    :
    : That goes for both C and C++.
    I didn't think about that, and like it, but I am doing UNICODE applications now, so shouldn't I be using wmemcpy() with wchar_t instead of memcpy() and char?

    -[italic][b][red]S[/red][purple]e[/purple][blue]p[/blue][green]h[/green][red]i[/red][purple]r[/purple][blue]o[/blue][green]t[/green][red]h[/red][/b][/italic]
  • : I didn't think about that, and like it, but I am doing UNICODE
    : applications now, so shouldn't I be using wmemcpy() with wchar_t
    : instead of memcpy() and char?
    :
    : -[italic][b][red]S[/red][purple]e[/purple][blue]p[/blue][green]h[/gre
    : en][red]i[/red][purple]r[/purple][blue]o[/blue][green]t[/green][red]h
    : [/red][/b][/italic]



    Nah, I don't see the point of that function honestly. memcpy() is general for all kind of data, and is not specific for strings.


    [code]int main()
    {
    wchar_t str[N];

    get_data(str, N*sizeof(wchar_t));

    }

    [/code]
  • : Alright, I know a class can access its own private members and
    : nothing else can, but what if I wanted to return a private member
    : using a public method? For example, I create an array of chars in a
    : class which are private. The end-developer may need to view this
    : data for some reason. I return a pointer to that array through a
    : public method. Could the developer use the pointer to change that
    : data, or just read it?
    : [code]:
    : class MyFakeClass
    : {
    : public:
    : MyFakeClass();
    : ~MyFakeClass();
    : char* ReturnMessage();
    :
    : private:
    : char *pBuffer;
    : };
    :
    : MyFakeClass::MyFakeClass()
    : {
    : this->pBuffer = new char[1024];
    : sprintf(this->pBuffer, "This is a pointless message!");
    : }
    :
    : MyFakeClass::~MyFakeClass()
    : {
    : delete[] this->pBuffer;
    : }
    :
    : char* MyFakeClass::ReturnMessage()
    : {
    : return this->pBuffer;
    : }
    :
    : //Somewhere in the main program loop...
    : char *pText;
    : MyFakeClass *pTemp;
    :
    : pTemp = new MyFakeClass;
    : pText = pTemp->ReturnMessage();
    : sprintf(pText, "This should cause an error!");
    : [/code]:
    : Would the sprintf() call crash the program or throw an exception as
    : it should, or will it simply overwrite the text in the array, which
    : it shouldn't?
    :
    : -[italic][b][red]S[/red][purple]e[/purple][blue]p[/blue][green]h[/gre
    : en][red]i[/red][purple]r[/purple][blue]o[/blue][green]t[/green][red]h
    : [/red][/b][/italic]

    as pointed by Lundin, though returning a pointer harms encapsulation, if you really need to pass private data through pointer, you can make the return type const *. This will make the private data read only for the outside of the class:
    [code]
    class MyFakeClass
    {
    public:
    MyFakeClass();
    ~MyFakeClass();
    const char* ReturnMessage();

    private:
    char *pBuffer;
    };
    //...
    const char* MyFakeClass::ReturnMessage()
    {
    return this->pBuffer;
    }[/code]
    [hr][purple]~Donotalo()[/purple]
Sign In or Register to comment.

Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Categories