private copy ctor problem 
Author Message
 private copy ctor problem

Hi,

I have this:

  class Example {
    public:
      // ...

      static Example loadObject(std::istream&);

    private:
      Example(const Example&);
  };

Now, when I use it like this

  void f(std::istream is)
  {
    const Example& ex = Example::loadObject(is);
  }

VC6 gives me C2248, saying it can't access the
copy ctor. I first thought this to be a bug of
VC6, but CodeWarrior does the same.
I don't understand. Why should the caller invoke
the copy ctor? What am I overlooking here?

Schobi

--

I'm HSchober at gmx dot de



Fri, 20 May 2005 21:05:41 GMT  
 private copy ctor problem

Quote:
> Hi,

> I have this:

>   class Example {
>     public:
>       // ...

>       static Example loadObject(std::istream&);

>     private:
>       Example(const Example&);
>   };

> Now, when I use it like this

>   void f(std::istream is)
>   {
>     const Example& ex = Example::loadObject(is);
>   }

> VC6 gives me C2248, saying it can't access the
> copy ctor. I first thought this to be a bug of
> VC6, but CodeWarrior does the same.
> I don't understand. Why should the caller invoke
> the copy ctor? What am I overlooking here?

Returning an object by value (which your loadObject does) requires an
accessible copy constructor.

-cd



Fri, 20 May 2005 22:27:43 GMT  
 private copy ctor problem

Quote:
> [...]
> Returning an object by value (which your loadObject does) requires an
> accessible copy constructor.

  Yeah, the question is: Accessible by whom?
  I never thought the caller would invoke the
  copy ctor.

Quote:
> -cd

  Schobi

--

I'm HSchober at gmx dot de



Fri, 20 May 2005 23:19:58 GMT  
 private copy ctor problem

Quote:

> > [...]
> > Returning an object by value (which your loadObject does) requires an
> > accessible copy constructor.

>   Yeah, the question is: Accessible by whom?
>   I never thought the caller would invoke the
>   copy ctor.

I did some rummaging around in the standard and was unable to find the point
where it's specified, but I'm certain that it is: the copy-constructor must
be accessible to the caller, just as it must be if an argument is passed
into the funciton by value.

-cd



Fri, 20 May 2005 23:34:02 GMT  
 private copy ctor problem
Hendrik,
Quote:
> > [...]
> > Returning an object by value (which your loadObject does) requires an
> > accessible copy constructor.

>   Yeah, the question is: Accessible by whom?
>   I never thought the caller would invoke the
>   copy ctor.

The copy ctor must be accessible within the scope of the caller.
(E.g. if f would be a static member of Example)

In your specific case the return value of loadObject would be
passed to the copy ctor of Example.

This ctor call would likely be elided by the optimizer but the
requirements for its accessibility still remain. [IIRC class.temporary]

regards
-hg



Sat, 21 May 2005 00:02:01 GMT  
 private copy ctor problem

Quote:
> [...]
> I did some rummaging around in the standard and was unable to find the point
> where it's specified, but I'm certain that it is: the copy-constructor must
> be accessible to the caller, just as it must be if an argument is passed
> into the funciton by value.

 Seems I learn something new about C++ every day.
 Thanks, Carl.

Quote:
> -cd

  Schobi

--

I'm HSchober at gmx dot de



Sat, 21 May 2005 00:19:10 GMT  
 private copy ctor problem

Quote:
> Hi,

> I have this:

>   class Example {
>     public:
>       // ...

>       static Example loadObject(std::istream&);

>     private:
>       Example(const Example&);
>   };

> Now, when I use it like this

>   void f(std::istream is)
>   {
>     const Example& ex = Example::loadObject(is);
>   }

> VC6 gives me C2248, saying it can't access the
> copy ctor. I first thought this to be a bug of
> VC6, but CodeWarrior does the same.
> I don't understand. Why should the caller invoke
> the copy ctor? What am I overlooking here?

> Schobi

> --

> I'm HSchober at gmx dot de

Some other though about copy ctor. You return an instance of the Example
class, right? So when you try to call this function outside of the Example
class, the system has to create a new instance of the Example somewhere,
take address of it and pass to your reference. In other words:

        const Example &ex = Example(Example::loadObject(is));

So that is why copy ctor must be accessible. You will not have this error
if you had a static Example data member and retrun a reference to it.

-d



Sat, 21 May 2005 11:00:41 GMT  
 private copy ctor problem

Quote:

> [...]
> Some other though about copy ctor. You return an instance of the Example
> class, right? So when you try to call this function outside of the Example
> class, the system has to create a new instance of the Example somewhere,
> take address of it and pass to your reference. In other words:

> const Example &ex = Example(Example::loadObject(is));

> So that is why copy ctor must be accessible.

  Yes. Only that until yesterday I thought that
  the called function would make that copy...

Quote:
>                                              You will not have this error
> if you had a static Example data member and retrun a reference to it.

  Well, but then I don't have the behaviour I
  need either. <g>
  I guess I need to think that through for
  another night in order to decide how I am
  going to change my design.

Quote:
> -d

  Schobi

--

I'm HSchober at gmx dot de



Sat, 21 May 2005 15:38:57 GMT  
 private copy ctor problem

Quote:
>   I guess I need to think that through for
>   another night in order to decide how I am
>   going to change my design.

What exactly are you trying to achieve?

-d



Sat, 21 May 2005 15:58:07 GMT  
 private copy ctor problem

Quote:

> >   I guess I need to think that through for
> >   another night in order to decide how I am
> >   going to change my design.

> What exactly are you trying to achieve?

  I have a objects which are stored within a managing
  object. Each of them has an ID. Outside of the manager
  they are referred to by their ID. The manager has full
  control over the life of all objects and it informs
  clients about any changes of any objects.
  When one puts an object into the hands of the manager,
  the latter returns the ID. The manager has functions
  which return const references to the objects when
  supplied with object IDs. One cannot change an object
  that's taken care of by the manager. Instead, one has
  to replace an existing object by a new one. (By calling
  a function which takes the object ID and the new object.)
  Internal to the manager, objects are stored in STL maps,
  requiring the manager to have access to the objects'
  copy ctors. However, otherwise, copying objects is
  forbidden. This ensures, that there won't be an object
  which isn't in the managers care, but has (obtained by
  copying) a valid ID.

  I've been working on the design and implementation of
  that part of the project for quite a while alone, having
  nothing but a bunch of testprograms to ensure what I do
  makes sense. It is just starting to be used by others
  who implement other parts of our project using this.
  However, they complain that they don't have a copy ctor
  accessible.
  While it is possible to copy objects in the way I
  want to allow this (i.e. without copying the internal
  ID as well), one has to call accessor functions on the
  rhs object for each attribute and pass the results to
  the lhs:

     void f(const MyObject& obj1)
     {
       MyObject obj2( obj1.getData1(), obj1.getData2(), .... );
     }

  I have to admit, that this is rather tedious. However,
  what's far more important to me is, that now the fact
  that this actually copies an object is not easy to see.

  That's where I thought, to do this:

     class MyObject {
       public:
         // ...
         MyObject makeCopy();
         // ...
         MyObject read(std::istream&);
         // ...
     }

  Unfortunately, as I learned yesterday, that doesn't
  work either.

  Right now I see two possibilities to solve that.
  One is, to make special ctors in the object which
  take some dummy argument and copy the way I want.
  The other is to make a 'CMyObjectCopy' class which
  hosts a copy and has copy ctors which again copy
  the way I want.
  While possible, that rather clutters the otherwise
  pretty straight design. So I'm still searching a
  more starightforward solution to this.

Quote:
> -d

  Schobi

--

I'm HSchober at gmx dot de



Sat, 21 May 2005 19:16:29 GMT  
 private copy ctor problem

Quote:

>>>  I guess I need to think that through for
>>>  another night in order to decide how I am
>>>  going to change my design.

>>What exactly are you trying to achieve?

>   I have a objects which are stored within a managing
>   object. Each of them has an ID. Outside of the manager
>   they are referred to by their ID. The manager has full
>   control over the life of all objects and it informs
>   clients about any changes of any objects.
>   When one puts an object into the hands of the manager,

This is not clear. You said that the manager (M) had full control over the
life of all objects. So I presumed that it created and destroyed them. But
in the next statement you say that an object is actually passed to M, that
is, it is _not_ created by M. The question is then, _what_ do you pass - a
pointer or a reference? Either way this is not *full* control since objects
are created ourside of M.

Quote:
>   the latter returns the ID. The manager has functions
>   which return const references to the objects when
>   supplied with object IDs. One cannot change an object
>   that's taken care of by the manager. Instead, one has
>   to replace an existing object by a new one. (By calling

And again, an old object is replaced by a new one created outside of M.

Quote:
>   a function which takes the object ID and the new object.)
>   Internal to the manager, objects are stored in STL maps,

Just to bring to your attention, STL maps are kind of slow. If you concern
about performance then you should change your maps to something else.

Quote:
>   requiring the manager to have access to the objects'
>   copy ctors. However, otherwise, copying objects is
>   forbidden. This ensures, that there won't be an object
>   which isn't in the managers care, but has (obtained by
>   copying) a valid ID.

All this sounds to me as the Object Factory pattern with a little twist
around object managing. If I were you I would take a look at Abstract
Factory, Factory Method, Prototype and in addition might be Singleton
patterns described in the GOF book, ISDN: 0201633612. Honestly, I do not
see much sense in describing them here but I believe that they will make
you change the way of your thinking which I consider not that quite
correct. Though, if you wish, I may send you their descriptions by email.
Just write me off.

-d



Sun, 22 May 2005 05:51:21 GMT  
 private copy ctor problem

Quote:

> [...]
> >   I have a objects which are stored within a managing
> >   object. Each of them has an ID. Outside of the manager
> >   they are referred to by their ID. The manager has full
> >   control over the life of all objects and it informs
> >   clients about any changes of any objects.
> >   When one puts an object into the hands of the manager,

> This is not clear. You said that the manager (M) had full control over the
> life of all objects. So I presumed that it created and destroyed them. But
> in the next statement you say that an object is actually passed to M, that
> is, it is _not_ created by M. The question is then, _what_ do you pass - a
> pointer or a reference? Either way this is not *full* control since objects
> are created ourside of M.

  You're right, of course. Objects are created
  outside. They are then passed to the manager
  by const reference. The manager stores copies
  of them. They are, however, not relevant to
  the "outside" unless the manager has them
  under its control.

Quote:
> >   the latter returns the ID. The manager has functions
> >   which return const references to the objects when
> >   supplied with object IDs. One cannot change an object
> >   that's taken care of by the manager. Instead, one has
> >   to replace an existing object by a new one. (By calling

> And again, an old object is replaced by a new one created outside of M.

  Yep.

Quote:
> >   a function which takes the object ID and the new object.)
> >   Internal to the manager, objects are stored in STL maps,

> Just to bring to your attention, STL maps are kind of slow. If you concern
> about performance then you should change your maps to something else.

  Thanks. We're talking less them 500 objects
  here, distributed over four maps. If speed
  ever becomes a problem, it's easy to switch
  to other data structures, since there's only
  one class (implementing that manager) directly
  accessing it.
  (Although, the question remains which data
  structure would give me faster lookup based on
  an internal numerical ID.)

Quote:
> >   requiring the manager to have access to the objects'
> >   copy ctors. However, otherwise, copying objects is
> >   forbidden. This ensures, that there won't be an object
> >   which isn't in the managers care, but has (obtained by
> >   copying) a valid ID.

> All this sounds to me as the Object Factory pattern with a little twist
> around object managing. If I were you I would take a look at Abstract
> Factory, Factory Method, Prototype and in addition might be Singleton
> patterns described in the GOF book, ISDN: 0201633612.

  In this case I don't see how Abstract Factory
  and Factory Method would help, since creating
  the objects isn't any problem. IIRC, Prototype
  as well deals with object creation. The manager
  (or, for the sake of a NDA, what we call manager
  here) has nothing to do with object creation.
  It's only task is to keep a bunch of objects
  and make sure, clients are notified when they
  change.
  The manager can't be a singleton, since there's
  managers needed at different places.

  The root of my problem is, that objects, once
  they got into the hand of the manager, shall
  not be allowed to change without having some
  clients knowing about this. My solution to the
  problem was to disallow changing of objects in
  the manager alltogether (by only giving const
  references tp them), leaving replacement done
  by the manager as the only way to change
  objects. This way the manager always knows,
  when objects change. Now clients can register
  with the manager and are called on the changes
  they subscribed to.
  However, now I need to copy objects in two
  different ways: An internal, which copies
  internal data as well, and a way accessible
  to everyone, which doesn't copy this data.
  Anyway, having boiled down the problem to this
  paragraph already helped me a lot. I can just
  have the objects have another copying ctor,
  which is public and does what i want.

Quote:
>                                                       Honestly, I do not
> see much sense in describing them here but I believe that they will make
> you change the way of your thinking which I consider not that quite
> correct. Though, if you wish, I may send you their descriptions by email.
> Just write me off.

  That book is on my desk. <g> I read it years
  ago, look up things once in a while and keep
  recommending it.

  Thanks for your time and insights!

Quote:
> -d

  Schobi

--

I'm hschober at gmx dot de



Mon, 23 May 2005 22:59:27 GMT  
 private copy ctor problem

Quote:

>>[...]

>   In this case I don't see how Abstract Factory
>   and Factory Method would help, since creating
>   the objects isn't any problem.

Yes, this is correct. If only you wanted to have everything under your
manager control, then it would make a difference otherwise it makes no sence.

 >   IIRC, Prototype

Quote:
>   as well deals with object creation. The manager
>   (or, for the sake of a NDA, what we call manager
>   here) has nothing to do with object creation.

And that was the thing that confused me. Perhaps, you have some other
_real_ object manager and this one serves only as a message dispatcher as
you said below.

Quote:
>   [...]
>   Anyway, having boiled down the problem to this
>   paragraph already helped me a lot. I can just
>   have the objects have another copying ctor,
>   which is public and does what i want.

In argument the truth is born :) Sometimes you need just to describe your
problem to somebody who even cannot make sense out of it and you will spot
a solution instantly. I do it a lot. The only thing that it makes you look
stupid if you ask too many questions :)

Good luck! Sorry for not giving new ideas.

-d



Tue, 24 May 2005 02:50:35 GMT  
 private copy ctor problem

Quote:

> [...]  The only thing that it makes you look
> stupid if you ask too many questions :)

  So what? ;^>

Quote:
> Good luck! Sorry for not giving new ideas.

  You did. (Just not where yout htought you would.)

Quote:
> -d

  Schobi

--

I'm HSchober at gmx dot de



Tue, 24 May 2005 19:35:05 GMT  
 
 [ 14 post ] 

 Relevant Pages 

1. access violation due to bad CString copy ctor when porting from VC6 to VC7 (VC++.NET)

2. Throw ignores access level of copy ctor and dtor

3. private copy c-tor vc error

4. private copy constructors

5. Problem with ctor overloads and property pages

6. Listing private members problem

7. std::bad_alloc ctor calls malloc????

8. Linker error for .ctor and Finalize in managed classes

9. User-defined ctor not exported from DLL

10. LINK : error LNK2020: unresolved token (060000EA) CMCNetToken::.ctor

11. C2440 with explicit template ctor

12. Initializing array elements in ctor-initial

 

 
Powered by phpBB® Forum Software