-2

I have a class called String with no ctor written, it has a private member

char s[maxlen+1];

which is not set until this method is called:

void assign (char const *st)
    {
        strcpy(s,st);
        len=strlen(st);
    }

In another class called Tick I have a member of type String

String name;

I want to write a copy constructor for the Tick class:

Tick::Tick( const Tick & obj )
{
        // Here are a bunch of primitive types copied
        // which I removed to keep it short
    name.assign(obj.name.s);
}

The String class does not have a return type for s, but I thought this should not be a problem as I have member name which is of type String and is able to access all members of an object of the same type. The compiler gives me the following error:

error C2248: 'String::s' : cannot access private member declared in class 'String'

user34920
  • 227
  • 3
  • 6
  • 12
  • Write a getter for `String::s`? – Brian Bi Jun 15 '14 at 22:47
  • Yes, I know that would solve the problem. However this bugs me as I am missing out on understanding something about C++ here... – user34920 Jun 15 '14 at 22:48
  • Your `assign` function is a terrible idea. It is far too easy for an accident to happen and to send in a string that is too big. The very utmost least thing you can do is use `strncpy`. – ghostofstandardspast Jun 15 '14 at 22:51
  • You must become one with the type. – Captain Obvlious Jun 15 '14 at 22:53
  • `name.assign(obj.name.s);` What should this be please`?!? It's completely unclear what you'r asking about! [MCVE](http://stackoverflow.com/help/mcve) please!! – πάντα ῥεῖ Jun 15 '14 at 22:54
  • You should design your class so that no other class needs access to `private` members. This is called *encapsulation*. Make all of your class's behaviour be defined by its `public` interface. Relying on anybody who wants to copy your String to call some particular operations on it, is a dreadful idea – M.M Jun 15 '14 at 22:55
  • @πάνταῥεῖ inside a copy ctor of class Tick, I want the String type member to be a copy of the member of the original object. name is the String type member and assign is a method of String. So I want to use it for accessing a private member of the name member of the original Tick object. – user34920 Jun 15 '14 at 23:01
  • @user34920 Please [add additional information to your question](http://stackoverflow.com/posts/24234768/edit) rather than trying to clarify in comments! You're way off doing all of this right BTW ([see also](http://stackoverflow.com/questions/4172722/what-is-the-rule-of-three), and check what other's told you about encapsulation). – πάντα ῥεῖ Jun 15 '14 at 23:02

2 Answers2

0

Because s is a private member in class String, only functions inside class String can access it. You could make a get function inside String to retrieve the s String::GetBuffer() const). Or you could just copy the string class instead of s.

NLScotty
  • 96
  • 1
  • 9
  • I tried to use name.assign() which is a function from within class String, as far as I understand it should be able to access private members. What do you mean copy the string class? – user34920 Jun 15 '14 at 22:51
  • Why would the tick class bother to know anything about a raw char array. Instead, copy the String class with a copy function (kind off like a copy constructor). That assign function seems not a String::Assign() function to me, maybe you forgot to post that piece. – NLScotty Jun 15 '14 at 22:54
  • The assign function was written inside the class declaration so it has "normal" syntax, I did not notice this is not obvious outside context. – user34920 Jun 15 '14 at 22:57
  • obj.name.s , that is the error. You are trying to acces a private member – NLScotty Jun 15 '14 at 22:58
  • That's true I somehow missed that! Thanks. – user34920 Jun 15 '14 at 23:03
0

You don't need to access s for this purpose. The default copy constructor for Tick will invoke the default copy constructor for String which will in turn copy s (assuming default copy constructors can be generated for both Tick and String).

If you need to write a custom copy constructor for Tick for other reasons, all you need to do to copy the String is:

name = obj.name;

That's what the default copy constructor for Tick would do.

So, if the default is sufficient, don't declare the copy constuctor for Tick at all. If it isn't, use the code above.

On a side note, an accessor to the underlying char array is useful when calling c-style APIs etc. Also, unless you really need a custom String class (really? are you sure?), use std::string.

Gyan aka Gary Buyn
  • 12,242
  • 2
  • 23
  • 26