3

I have a class A which has an reference to an object of class B as a member. The copy constructor (and assignment operator) of class B is private. Do you think it is a valid and good idea to use the default copy constructor for A. (I actually want a functionality where I can store a lots of object for type A in some sort of an STL Container which requires both assign-ability and copy-ability.)

class A
{
    private:
        B& b_;

    public:
        A(B& b) : b_(b){}
}

Till now, in my knowledge the objections to above method are the following but my design does not face it. I would like to know if there are some other problems/issues/concerns about the above example...

  1. Only the reference is copied and hence, there would be problems when the original object b of type B is destroyed. (Does not apply, because b is available throughout the entire scope.)
  2. Is b_ unique for every instance of A? (No, B is actually instantiated only once in the scope, so it has the effect of a singleton class.)

If there are other concerns, please list them here. I am not keen on a explicitly defined copy-constructor but i'm keeping an open mind towards it.

  • 1
    `A` won't be default-constructible, so you cannot use it in the standard containers. – Kerrek SB Jul 27 '11 at 16:00
  • 1
    A doesn´t need to be default-constructible to be used in any stl containers. You need the default constructor just for the c-array – Alessandro Teruzzi Jul 27 '11 at 16:05
  • @Alessandro: Very interesting, I always thought that was a requirement! Did that change in C++0x, or has that always been the case? (That said, the OP's `A` won't be copy or move constructible, so it cannot be used in the standard containers.) – Kerrek SB Jul 27 '11 at 16:14
  • @Kerrek: some constructors and member functions use `T()` as a default argument, and those of course require default-construction. Same goes for `map::operator[]`, which default-constructs the value type. Other than that (and any other specific uses I've forgotten) it's not stated as a requirement. 23.1/3 states the general requirements. – Steve Jessop Jul 27 '11 at 18:32
  • @Steve 23.1/3 of what? C++ standard 2003? –  Jul 28 '11 at 09:26
  • btw.. do you think the compiler would be able to provide a default assignment operator? –  Jul 29 '11 at 11:16

4 Answers4

3

As a general guideline, I never store references inside objects because I cannot get copy semantics for free.

I store pointers instead. Here, storing a dumb pointer and letting the compiler implement copy semantics for you seems fine:

class A
{
    B* b; // or a smart pointer, depending on what semantics you want.

public:
    A(B& b) : b(&b) {}
};

Using a pointer has some flexibility: for instance, default construction can set the pointer to zero, and subsequent operations check against its validity (or simply assert). Also, the pointer can be reset, which is not the case with a reference.

Alexandre C.
  • 55,948
  • 11
  • 128
  • 197
2

Check the Rule of Three.
If you need to overload any one of these(destructor, copy constructor & copy assignment operator) three you need to overload all of them. If you don't overload any of these then you can rely on the default functions the compiler generates.

Community
  • 1
  • 1
Alok Save
  • 202,538
  • 53
  • 430
  • 533
0

You aren't storing a B by value and you understand the lifetime issues (they apply regardless if copying it around) so I think it's fine to use the default copy constructor.

As a side note I do recommend making the A(B&) constructor explicit to avoid implicitly treating a B as an A.

Mark B
  • 95,107
  • 10
  • 109
  • 188
  • btw... i guess i have already made the constructor explicit.... do you want to say it should be more explicit? if yes.. then how? –  Jul 29 '11 at 15:11
0

If assignment operator of B is private, then the compiler cannot generated a default a assignemnt operator for A. You will have to declare a assignment operator explicitly. Otherwise you got a compile error : http://msdn.microsoft.com/en-us/library/aa983787%28v=vs.71%29.aspx

Once you done that, you should have no problem put object A into STL container.

RoundPi
  • 5,819
  • 7
  • 49
  • 75
  • ohk... hmm... i want an assignment operator for A anyway... so i'll write one i guess.. thanks........ –  Jul 28 '11 at 04:17
  • i saw the link... i'm not sure it is the same thing... i'll try out the code though and let you know what happens...... if there is no default assignment operator.. i'll implement it i guess...... –  Jul 28 '11 at 09:20
  • but B is not copyable... how am i going to define an assignment operator? –  Jul 29 '11 at 04:04
  • Sorry my mistake, I think I mis-read your question and brought up a different issue(as you can see from the link above). As your's is neither inheritance from B nor holding B object directly, instead you were holding a reference to B object, so the default copy constructor should do the trick. But please note the reference syntax means class A doesn't own B. – RoundPi Jul 29 '11 at 09:04