2

I am dealing with a class that I cannot tamper with. This is basically what I have:

class Base
{
    public:
        static Base factoryBase()
        {
            return Base();
        }

    protected:
        Base() {};
        Base(Base const & other) {  }
        Base & operator=(Base const & other) { return *this; }
};

In essence I have a static factory method, to instantiate the Base class.

In my part of the code I want to do this

Base b = Base::factoryBase(); 

but this fails because the copy constructor and assignment operator are protected. I can only assume that they are so, so that I can use them in a derived class.

How should I go about it though?

class Derived : public Base
{
    public:
        Derived()
        {
            //Base::factoryBase(); //what do I do here and how do I store the result?
        }
};

I am unsure how to assign the result of Base::factoryBase() to the Derived class itself. Is it even possible? How else am I supposed to use the fact that the constructors and assignment operators are protected ?

note: compilation is done with earlier that c++11 versions. Thank you for your help

nass
  • 1,453
  • 1
  • 23
  • 38
  • It is strange to me that the copy constructor is even being invoked, that copy should be elided due to [RVO](https://stackoverflow.com/questions/12953127/what-are-copy-elision-and-return-value-optimization). – Cory Kramer Jan 12 '17 at 18:18
  • Wouldn't `const Base &b = Base::factoryBase();` work? Or does that still check the copy constructor? – melpomene Jan 12 '17 at 18:26
  • @CoryKramer: Even if copy elision could occurs, copy(/move) constructor should be accessible. – Jarod42 Jan 12 '17 at 18:46
  • @melpomene: `const Base &b = Base::factoryBase();` (or `Base&& b = Base::factoryBase();` in c++11) should work. – Jarod42 Jan 12 '17 at 18:46
  • @Jarod42 Even if you ignore the copy constructor, don't forget that `operator=` is also protected. Assigning to any `Base` object, regardless of cv/ref qualifiers, should fail from outside. – 0x5453 Jan 12 '17 at 18:54
  • @0x5453: `Base b = Base::factoryBase();` calls copy/move constructor, not assignment. – Jarod42 Jan 12 '17 at 19:06
  • @Jarod42 Whoops, you're right. Forgot about that. – 0x5453 Jan 12 '17 at 19:25

2 Answers2

3

You may still do:

class Derived : public Base
{
public:
    Derived() : Base(/*Base::factoryBase()*/) {}

    // Not really useful, but for demonstration
    static Derived factoryDerived() { return Derived(); }
};

And then

Derived d = Derived::factoryDerived();
Jarod42
  • 203,559
  • 14
  • 181
  • 302
  • Hi there, why do you have `Base(/*Base::factoryBase()*/)`? Is it possible to avoid calling the `Base()` constructor and rely on the static `factoryBase()`? – nass Jan 13 '17 at 09:10
  • @nass: That is the reason of the comment, you might copy construct from the factory if you prefer (by un-commenting that part). – Jarod42 Jan 13 '17 at 12:22
1

You could call operator= directly in the derived class:

Derived()
{
    Base::operator=(Base::factoryBase());
}
Graphene
  • 41
  • 5